gtk/makefile.msc
gtk/gtkversion.h
gtk/gtk-win32.rc
+gtk/a11y/Makefile
+gtk/a11y/libgail-util/Makefile
+gtk/a11y/tests/Makefile
gtk/tests/Makefile
modules/Makefile
-modules/other/Makefile
-modules/other/gail/Makefile
-modules/other/gail/libgail-util/Makefile
-modules/other/gail/tests/Makefile
modules/engines/Makefile
modules/engines/pixbuf/Makefile
modules/engines/ms-windows/Makefile
GTK_PRINT_PREVIEW_COMMAND="evince --unlink-tempfile --preview --print-settings %s %f"
endif
-SUBDIRS = . tests
+SUBDIRS = . a11y tests
if HAVE_PAPI_CUPS
GTK_PRINT_BACKENDS=file,papi,cups
--- /dev/null
+=== ChangeLog discontinued ===
+
+ With the move to git, GTK+ is switching from a ChangeLog file
+ to relying on commit messages to provide change history. Please
+ see README.commits for guidance on the expected message format.
+
+2009-03-25 Tor Lillqvist <tml@novell.com>
+
+ Bug 575644 - Cygwin gail build patch
+
+ * modules/other/gail/Makefile.am
+ * modules/other/gail/libgail-util/Makefile.am
+ * modules/other/gail/tests/Makefile.am: Use -no-undefined also on
+ Cygwin. Patch from "Cygwin ports maintainer".
+
+2009-03-13 Matthias Clasen <mclasen@redhat.com>
+
+ * === Released 2.16.0 ===
+
+2009-03-02 Matthias Clasen <mclasen@redhat.com>
+
+ * === Released 2.15.5 ===
+
+2009-02-26 Li Yuan <li.yuan@sun.com>
+
+ * Makefile.am:
+ * gail.c: (gail_accessibility_module_init):
+ * gail.h:
+ * gailscalebutton.c: (gail_scale_button_class_init),
+ (gail_scale_button_init), (gail_scale_button_initialize),
+ (atk_action_interface_init), (gail_scale_button_do_action),
+ (gail_scale_button_get_n_actions),
+ (gail_scale_button_get_description),
+ (gail_scale_button_action_get_name),
+ (gail_scale_button_get_keybinding),
+ (gail_scale_button_set_description), (atk_value_interface_init),
+ (gail_scale_button_get_current_value),
+ (gail_scale_button_get_maximum_value),
+ (gail_scale_button_get_minimum_value),
+ (gail_scale_button_get_minimum_increment),
+ (gail_scale_button_set_current_value),
+ (gail_scale_button_notify_gtk):
+ * gailscalebutton.h:
+ Bug #519090. Add accessibility support to GtkScaleButton.
+ Support action and value interfaces. Patch from Jan Arne Petersen.
+
+2009-02-26 Li Yuan <li.yuan@sun.com>
+
+ * gailbutton.c: (idle_do_action):
+ Bug #561631. Patch from Yue Wang. Ref the button in the idle
+ function to prevent the button being finalized.
+
+2009-02-25 Li Yuan <li.yuan@sun.com>
+
+ * gailtreeview.c: (gail_tree_view_ref_accessible_at_point):
+ Bug #325809. Get the cell from the coordinates based on
+ bin_window.
+
+2009-02-25 Li Yuan <li.yuan@sun.com>
+
+ * gailentry.c: (gail_entry_real_notify_gtk),
+ (gail_entry_idle_notify_insert), (_gail_entry_insert_text_cb):
+ Bug #520395. Notify the insert signal in the idle function. Let
+ text_util has chance to update cache.
+
+2009-02-25 Li Yuan <li.yuan@sun.com>
+
+ * gailtreeview.c: (is_cell_showing):
+ Bug #571001. Set the cell's showing state based on bin_window
+ coordinates.
+
+2009-02-17 Matthias Clasen <mclasen@redhat.com>
+
+ * === Released 2.15.4 ===
+
+2009-02-17 Li Yuan <li.yuan@sun.com>
+
+ * gailbutton.c: (idle_do_action):
+ Bug #561631. Use g_queue_get_length to determine if a queue is empty.
+
+2009-02-04 Tor Lillqvist <tml@novell.com>
+
+ Bug 570406 - gailutil.def is in srcdir, but used from builddir
+
+ * libgail-util/Makefile.am: Use gailutil.def from srcdir. Drop
+ useless rules to install/uninstall import libraries, libtool knows
+ to install / uninstall them itself when installing / uninstalling
+ a .la file. Add rules to install / uninstall the def file like for
+ consistency, like with the other libraries in GTK+.
+
+2009-02-02 Matthias Clasen <mclasen@redhat.com>
+
+ * === Released 2.15.3 ===
+
+2009-01-27 Matthias Clasen <mclasen@redhat.com>
+
+ * === Released 2.15.2 ===
+
+2009-01-23 Matthias Clasen <mclasen@redhat.com>
+
+ * === Released 2.15.1 ===
+
+2009-01-07 Brad Taylor <brad@getcoded.net>
+
+ * gail.c:
+ Bug #565110 – Add an env variable to disable Gail.
+
+2009-01-01 Matthias Clasen <mclasen@redhat.com>
+
+ * === Released 2.15.0 ===
+
+2008-12-21 Tor Lillqvist <tml@novell.com>
+
+ * gaillabel.c: #undef GTK_DISABLE_DEPRECATED here, too, to get
+ GTK_IS_COMBO.
+
+2008-12-15 Li Yuan <li.yuan@sun.com>
+
+ * gailitem.c:
+ Bug #564555. #undef GTK_DISABLE_DEPRECATED where we need to access
+ deprecated symbols.
+
+2008-12-12 Li Yuan <li.yuan@sun.com>
+
+ * gailtreeview.c: Bug #512743.
+ (gail_tree_view_changed_gtk): Clean cell before go through the info
+ list, for "changed" signal could come before a "row-deleted".
+ (clean_cell_info):
+ Prevent the thread to be scheduled before clean_cell_info
+ finish its job.
+
+2008-12-09 Michael Natterer <mitch@imendio.com>
+
+ * Makefile.am
+ * tests/Makefile.am: add GTK_DISABLE_DEPRECATED to CFLAGS.
+
+ * gail.c
+ * gailclist.c
+ * gailclistcell.c
+ * gailcombo.c
+ * gaillist.c
+ * gailmenu.c
+ * gailoptionmenu.c
+ * gailpixmap.c
+ * gailprogressbar.c
+ * gailtoplevel.c
+ * gailwidget.c
+ * gailwindow.c
+ * tests/ferret.c
+ * tests/testcombo.c
+ * tests/testlib.h
+ * tests/testoptionmenu.c: #undef it where we need to access
+ deprecated cruft.
+
+2008-12-09 Michael Natterer <mitch@imendio.com>
+
+ * gailtreeview.c: undeprecate.
+
+2008-11-27 Matthias Clasen <mclasen@redhat.com>
+
+ Bug 353088 – gtk_expander_get_label should return the full label text
+
+ * gailexpander.c: Don't rely on gtk_expander_get_label.
+ Patch by Peter Johanson.
+
+2008-11-24 Li Yuan <li.yuan@sun.com>
+
+ * gailnotebook.c: (gail_notebook_page_added):
+ Bug #554002. Add cache's page count when add pages.
+
+2008-10-13 Matthias Clasen <mclasen@redhat.com>
+
+ Bug 555953 – libferret missing link against libgtk-x11
+
+ * test/Makefile.am: Link libferret against gtk.
+
+2008-10-07 Matthias Clasen <mclasen@redhat.com>
+
+ Bug 554950 – gail must make itself resident
+
+ * gail.c: Make the module resident, since it can't handle
+ being unloaded.
+
+2008-09-22 Michael Natterer <mitch@imendio.com>
+
+ * tests/ferret.c: s/GTK_SIGNAL_FUNC/G_CALLBACK/
+
+2008-09-20 Matthias Clasen <mclasen@redhat.com>
+
+ * gailtextview.c:
+ * gailbutton.c: Fix possible leaks of textutils.
+
+2008-09-19 Matthias Clasen <mclasen@redhat.com>
+
+ * gailtreeview.c (garbage_collect_cell_data): Actually free
+ the copied list.
+
+2008-08-21 Li Yuan <li.yuan@sun.com>
+
+ * gailtreeview.c: (traverse_cells):
+ Bug #548783. Change g_assert to g_return_if_fail to avoid
+ unnucessary crash.
+
+2008-08-21 Li Yuan <li.yuan@sun.com>
+
+ * gailtreeview.c: (model_row_deleted):
+ Bug #548782. Emit children-changed::remove signal when a row is
+ deleted in gtktreeview.
+
+2008-08-15 Michael Natterer <mitch@imendio.com>
+
+ * gailbooleancell.c
+ * gailimagecell.c
+ * gailtextcell.c
+ * gailwidget.c
+ * tests/Makefile.am
+ * tests/testbutton.c
+ * tests/testimage.c
+ * tests/testlib.c
+ * tests/testmenuitem.c
+ * tests/testnotebook.c
+ * tests/testoptionmenu.c
+ * tests/testpaned.c
+ * tests/testselection.c
+ * tests/testtable.c: some undeprecation.
+
+ * libgail-util/Makefile.am. build with GDK_DISABLE_DEPRECATED
+ and GTK_DISABLE_DEPRECATED.
+
+2008-08-11 Michael Natterer <mitch@imendio.com>
+
+ * tests/ferret.c
+ * tests/testlib.c
+ * tests/testtable.c: don't use the deprecated
+ gtk_box_pack_start_defaults()
+
+2008-08-04 Tor Lillqvist <tml@novell.com>
+
+ * libgail-util/Makefile.am: Pass appropriate -machine flag to
+ lib.exe.
+
+2008-07-02 Li Yuan <li.yuan@sun.com>
+
+ * gailoptionmenu.c: (gail_option_menu_real_initialize),
+ (gail_option_menu_changed):
+ Bug #541167. Emit "object:property-change:accessible-name" when
+ GailOptionMenui's name changes.
+
+2008-06-18 Michael Natterer <mitch@imendio.com>
+
+ * gailimage.c (gail_image_get_image_size)
+ * gailpixmap.c (gail_pixmap_get_image_size):
+ s/gdk_window_get_size/gdk_drawable_get_size/
+
+2008-06-17 Michael Natterer <mitch@imendio.com>
+
+ * gail.c
+ * gailtoplevel.c: s/gtk_type_class/g_type_class_ref/
+
+ * Makefile.am: add GDK_DISABLE_DEPRECATED to CPPFLAGS.
+
+2008-06-10 Li Yuan <li.yuan@sun.com>
+
+ * gailtextview.c: (gail_text_view_set_caret_offset):
+ Automatically scroll text caret to make it visible, when AT
+ sets its offset.
+
+2008-06-06 Li Yuan <li.yuan@sun.com>
+
+ * gail/gaillabel.c: (gail_label_real_notify_gtk):
+ Before emitting "text_caret_moved", change the cursor to the
+ changed bound. Bug #536927.
+
+2008-05-30 Michael Natterer <mitch@imendio.com>
+
+ * gailcellparent.h
+ * gailfactory.h
+ * tests/testnotebook.c
+ * tests/testtext.c
+ * tests/testtoplevel.c
+ * tests/testvalues.c: include <atk/atk.h> instead of individual
+ files from ATK.
+
+2008-05-28 Michael Natterer <mitch@imendio.com>
+
+ * gailwidget.h: include <gtk/gtk.h> instead of
+ <gtk/gtkaccessible.h>
+
+ * *.h: don't include anyting from gtk since all headers indirectly
+ include gailwidget.h.
+
+ * gailcellparent.c: include <gtk/gtk.h> instead of individual
+ files.
+
+ * gailcheckmenuitem.c
+ * gailmenu.c
+ * gailtreeview.c: remove all gtk includes since it's always
+ included by including any gail header.
+
+2008-05-26 Michael Natterer <mitch@imendio.com>
+
+ * libgail-util/gailmisc.h
+ * libgail-util/gailtextutil.h: use G_BEGIN/END_DECLS.
+
+2008-05-24 Matthias Clasen <mclasen@redhat.com>
+
+ Bug 504706 – wrong deallocator used for GError in gailtextview.c
+
+ * gailtextview.c: Don't use g_free on a GError.
+
+2008-04-02 Li Yuan <li.yuan@.sun.com>
+
+ * gailbutton.c: (idle_do_action):
+ Patch from Alejandro Piñeiro Iglesias <apinheiro@igalia.com>.
+ Bug #496167. Synthesize press and release GdkEvent in button's click
+ action.
+
+2008-03-31 Li Yuan <li.yuan@sun.com>
+
+ * gailbutton.c: (gail_button_ref_state_set):
+ Bug #433324. add/remove selectable state depand on if the button can
+ be focused.
+
+2008-03-20 Li Yuan <li.yuan@sun.com>
+
+ * gailcell.c: (gail_cell_object_finalize):
+ Bug #498079. Free cell's action info before free the action_list.
+
+2008-01-11 Li Yuan <li.yuan@sun.com>
+
+ * gailtreeview.c: (gail_tree_view_real_initialize), (focus_in),
+ (focus_out):
+ Bug #508255. Remove ATK_STATE_FOCUSED state when focus jumps out.
+ Emit "active-descendant-changed" and add ATK_STATE_FOCUSED state when
+ focus comes in again.
+
+2008-01-11 Li Yuan <li.yuan@sun.com>
+
+ * gailtreeview.c: (gail_tree_view_ref_child),
+ (idle_cursor_changed):
+ Bug #497218. Emit "active-descendant-changed" when focus first comes
+ into treeview. Add/remove ATK_STATE_FOCUSED when cursor changes.
+
+2008-01-11 Li Yuan <li.yuan@sun.com>
+
+ * gailtreeview.c: (gail_tree_view_get_n_rows):
+ Bug #508715. Should use gtk_tree_path_free to free a GtkTreePath.
+
--- /dev/null
+include $(top_srcdir)/Makefile.decl
+
+SUBDIRS = libgail-util tests
+
+if PLATFORM_WIN32
+no_undefined = -no-undefined
+endif
+
+moduledir = $(libdir)/gtk-3.0/modules
+module_LTLIBRARIES = libgail.la
+
+gail_c_sources = \
+ gail-private-macros.h \
+ gail.c \
+ gailadjustment.c \
+ gailarrow.c \
+ gailbooleancell.c \
+ gailbox.c \
+ gailbutton.c \
+ gailcalendar.c \
+ gailcell.c \
+ gailcellparent.c \
+ gailcheckmenuitem.c \
+ gailchecksubmenuitem.c \
+ gailcombobox.c \
+ gailcontainer.c \
+ gailcontainercell.c \
+ gailentry.c \
+ gailexpander.c \
+ gailframe.c \
+ gailimage.c \
+ gailimagecell.c \
+ gaillabel.c \
+ gaillinkbutton.c \
+ gailmenu.c \
+ gailmenushell.c \
+ gailmenuitem.c \
+ gailnotebook.c \
+ gailnotebookpage.c \
+ gailpaned.c \
+ gailprogressbar.c \
+ gailradiobutton.c \
+ gailradiomenuitem.c \
+ gailradiosubmenuitem.c \
+ gailrange.c \
+ gailrenderercell.c \
+ gailscale.c \
+ gailscalebutton.c \
+ gailscrollbar.c \
+ gailscrolledwindow.c \
+ gailseparator.c \
+ gailspinbutton.c \
+ gailsubmenuitem.c \
+ gailstatusbar.c \
+ gailtextcell.c \
+ gailtextview.c \
+ gailtogglebutton.c \
+ gailtoplevel.c \
+ gailtreeview.c \
+ gailutil.c \
+ gailwidget.c \
+ gailwindow.c
+
+libgailincludedir=$(includedir)/gail-3.0/gail
+
+gail_private_h_sources = \
+ gail.h \
+ gailadjustment.h \
+ gailarrow.h \
+ gailbooleancell.h \
+ gailbox.h \
+ gailbutton.h \
+ gailcalendar.h \
+ gailcell.h \
+ gailcellparent.h \
+ gailcheckmenuitem.h \
+ gailchecksubmenuitem.h \
+ gailcombobox.h \
+ gailcontainercell.h \
+ gailcontainer.h \
+ gailentry.h \
+ gailexpander.h \
+ gailfactory.h \
+ gailframe.h \
+ gailimage.h \
+ gailimagecell.h \
+ gaillabel.h \
+ gaillinkbutton.h \
+ gailmenu.h \
+ gailmenushell.h \
+ gailmenuitem.h \
+ gailnotebook.h \
+ gailnotebookpage.h \
+ gailpaned.h \
+ gailprogressbar.h \
+ gailradiobutton.h \
+ gailradiomenuitem.h \
+ gailradiosubmenuitem.h \
+ gailrange.h \
+ gailrenderercell.h \
+ gailscale.h \
+ gailscalebutton.h \
+ gailscrollbar.h \
+ gailscrolledwindow.h \
+ gailseparator.h \
+ gailspinbutton.h \
+ gailsubmenuitem.h \
+ gailstatusbar.h \
+ gailtextcell.h \
+ gailtextview.h \
+ gailtogglebutton.h \
+ gailtoplevel.h \
+ gailtreeview.h \
+ gailutil.h \
+ gailwindow.h
+
+gail_public_h_sources = \
+ gailwidget.h
+
+libgail_la_SOURCES = \
+ $(gail_c_sources) \
+ $(gail_public_h_sources) \
+ $(gail_private_h_sources)
+
+libgailinclude_HEADERS = \
+ $(gail_public_h_sources)
+
+libgail_la_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/gdk \
+ -I$(top_builddir)/gdk \
+ -I$(top_srcdir)/gtk \
+ -I$(top_builddir)/gtk \
+ -DGTK_VERSION=\"$(GTK_VERSION)\"\
+ -DGDK_DISABLE_DEPRECATED \
+ -DGTK_DISABLE_DEPRECATED \
+ $(AM_CPPFLAGS)
+
+libgail_la_CFLAGS = \
+ $(GTK_DEP_CFLAGS) \
+ $(GTK_DEBUG_FLAGS) \
+ $(AM_CFLAGS)
+
+libgail_la_LIBADD = \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gtk/a11y/libgail-util/libgailutil-3.la \
+ $(GTK_DEP_LIBS) \
+ $(INTLLIBS)
+
+libgail_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version \
+ $(no_undefined) \
+ $(LDFLAGS)
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GAIL_PRIVATE_MACROS_H__
+#define __GAIL_PRIVATE_MACROS_H__
+
+G_BEGIN_DECLS
+
+/* Note: these macros are logic macros, not intended to warn on failure. */
+
+#define gail_return_val_if_fail(a, b) if (!(a)) return (b)
+#define gail_return_if_fail(a) if (!(a)) return
+
+G_END_DECLS
+
+#endif /* __GAIL_PRIVATE_MACROS_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <gtk/gtkx.h>
+#include "gail.h"
+#include "gailfactory.h"
+
+#define GNOME_ACCESSIBILITY_ENV "GNOME_ACCESSIBILITY"
+#define NO_GAIL_ENV "NO_GAIL"
+
+static gboolean gail_focus_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static gboolean gail_select_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static gboolean gail_deselect_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static gboolean gail_switch_page_watcher(GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static AtkObject* gail_get_accessible_for_widget (GtkWidget *widget,
+ gboolean *transient);
+static void gail_finish_select (GtkWidget *widget);
+static void gail_map_cb (GtkWidget *widget);
+static void gail_map_submenu_cb (GtkWidget *widget);
+static gint gail_focus_idle_handler (gpointer data);
+static void gail_focus_notify (GtkWidget *widget);
+static void gail_focus_notify_when_idle (GtkWidget *widget);
+
+static void gail_focus_tracker_init (void);
+static void gail_focus_object_destroyed (gpointer data);
+static void gail_focus_tracker (AtkObject *object);
+static void gail_set_focus_widget (GtkWidget *focus_widget,
+ GtkWidget *widget);
+static void gail_set_focus_object (AtkObject *focus_obj,
+ AtkObject *obj);
+
+GtkWidget* focus_widget = NULL;
+static GtkWidget* next_focus_widget = NULL;
+static gboolean was_deselect = FALSE;
+static GtkWidget* subsequent_focus_widget = NULL;
+static GtkWidget* focus_before_menu = NULL;
+static guint focus_notify_handler = 0;
+static guint focus_tracker_id = 0;
+static GQuark quark_focus_object = 0;
+
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WIDGET, GailWidget, gail_widget, GTK_TYPE_WIDGET)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_CONTAINER, GailContainer, gail_container, GTK_TYPE_CONTAINER)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_BUTTON, GailButton, gail_button, GTK_TYPE_BUTTON)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_LINK_BUTTON, GailLinkButton, gail_link_button, GTK_TYPE_LINK_BUTTON)
+GAIL_IMPLEMENT_FACTORY_WITH_FUNC (GAIL_TYPE_MENU_ITEM, GailMenuItem, gail_menu_item, gail_menu_item_new)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_TOGGLE_BUTTON, GailToggleButton, gail_toggle_button, GTK_TYPE_TOGGLE_BUTTON)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_IMAGE, GailImage, gail_image, GTK_TYPE_IMAGE)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_TEXT_VIEW, GailTextView, gail_text_view, GTK_TYPE_TEXT_VIEW)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_COMBO_BOX, GailComboBox, gail_combo_box, GTK_TYPE_COMBO_BOX)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_ENTRY, GailEntry, gail_entry, GTK_TYPE_ENTRY)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU_SHELL, GailMenuShell, gail_menu_shell, GTK_TYPE_MENU_SHELL)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU, GailMenu, gail_menu, GTK_TYPE_MENU)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WINDOW, GailWindow, gail_window, GTK_TYPE_BIN)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_RANGE, GailRange, gail_range, GTK_TYPE_RANGE)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCALE, GailScale, gail_scale, GTK_TYPE_SCALE)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCALE_BUTTON, GailScaleButton, gail_scale_button, GTK_TYPE_SCALE_BUTTON)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_LABEL, GailLabel, gail_label, GTK_TYPE_LABEL)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_STATUSBAR, GailStatusbar, gail_statusbar, GTK_TYPE_STATUSBAR)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_NOTEBOOK, GailNotebook, gail_notebook, GTK_TYPE_NOTEBOOK)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_CALENDAR, GailCalendar, gail_calendar, GTK_TYPE_CALENDAR)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_PROGRESS_BAR, GailProgressBar, gail_progress_bar, GTK_TYPE_PROGRESS_BAR)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SPIN_BUTTON, GailSpinButton, gail_spin_button, GTK_TYPE_SPIN_BUTTON)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_TREE_VIEW, GailTreeView, gail_tree_view, GTK_TYPE_TREE_VIEW)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_FRAME, GailFrame, gail_frame, GTK_TYPE_FRAME)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_RADIO_BUTTON, GailRadioButton, gail_radio_button, GTK_TYPE_RADIO_BUTTON)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_ARROW, GailArrow, gail_arrow, GTK_TYPE_ARROW)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SEPARATOR, GailSeparator, gail_separator, GTK_TYPE_SEPARATOR)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_BOX, GailBox, gail_box, GTK_TYPE_BOX)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCROLLED_WINDOW, GailScrolledWindow, gail_scrolled_window, GTK_TYPE_SCROLLED_WINDOW)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_PANED, GailPaned, gail_paned, GTK_TYPE_PANED)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCROLLBAR, GailScrollbar, gail_scrollbar, GTK_TYPE_SCROLLBAR)
+GAIL_IMPLEMENT_FACTORY_WITH_FUNC (GAIL_TYPE_CHECK_MENU_ITEM, GailCheckMenuItem, gail_check_menu_item, gail_check_menu_item_new)
+GAIL_IMPLEMENT_FACTORY_WITH_FUNC (GAIL_TYPE_RADIO_MENU_ITEM, GailRadioMenuItem, gail_radio_menu_item, gail_radio_menu_item_new)
+GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_EXPANDER, GailExpander, gail_expander, GTK_TYPE_EXPANDER)
+GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_RENDERER_CELL, GailRendererCell, gail_renderer_cell, GTK_TYPE_CELL_RENDERER, gail_renderer_cell_new)
+GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_BOOLEAN_CELL, GailBooleanCell, gail_boolean_cell, GTK_TYPE_CELL_RENDERER_TOGGLE, gail_boolean_cell_new)
+GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_IMAGE_CELL, GailImageCell, gail_image_cell, GTK_TYPE_CELL_RENDERER_PIXBUF, gail_image_cell_new)
+GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_TEXT_CELL, GailTextCell, gail_text_cell, GTK_TYPE_CELL_RENDERER_TEXT, gail_text_cell_new)
+
+static AtkObject*
+gail_get_accessible_for_widget (GtkWidget *widget,
+ gboolean *transient)
+{
+ AtkObject *obj = NULL;
+ GType gnome_canvas;
+
+ gnome_canvas = g_type_from_name ("GnomeCanvas");
+
+ *transient = FALSE;
+ if (!widget)
+ return NULL;
+
+ if (GTK_IS_ENTRY (widget))
+ ;
+ else if (GTK_IS_NOTEBOOK (widget))
+ {
+ GtkNotebook *notebook;
+ gint page_num = -1;
+
+ notebook = GTK_NOTEBOOK (widget);
+ page_num = gtk_notebook_get_current_page (notebook);
+ if (page_num != -1)
+ {
+ obj = gtk_widget_get_accessible (widget);
+ obj = atk_object_ref_accessible_child (obj, page_num);
+ g_object_unref (obj);
+ }
+ }
+ else if (G_TYPE_CHECK_INSTANCE_TYPE ((widget), gnome_canvas))
+ {
+ GObject *focused_item;
+ GValue value = {0, };
+
+ g_value_init (&value, G_TYPE_OBJECT);
+ g_object_get_property (G_OBJECT (widget), "focused_item", &value);
+ focused_item = g_value_get_object (&value);
+
+ if (focused_item)
+ {
+ AtkObject *tmp;
+
+ obj = atk_gobject_accessible_for_object (G_OBJECT (focused_item));
+ tmp = g_object_get_qdata (G_OBJECT (obj), quark_focus_object);
+ if (tmp != NULL)
+ obj = tmp;
+ }
+ }
+ else if (GTK_IS_TOGGLE_BUTTON (widget))
+ {
+ GtkWidget *other_widget = gtk_widget_get_parent (widget);
+ if (GTK_IS_COMBO_BOX (other_widget))
+ {
+ gail_set_focus_widget (other_widget, widget);
+ widget = other_widget;
+ }
+ }
+ if (obj == NULL)
+ {
+ AtkObject *focus_object;
+
+ obj = gtk_widget_get_accessible (widget);
+ focus_object = g_object_get_qdata (G_OBJECT (obj), quark_focus_object);
+ /*
+ * We check whether the object for this focus_object has been deleted.
+ * This can happen when navigating to an empty directory in nautilus.
+ * See bug #141907.
+ */
+ if (ATK_IS_GOBJECT_ACCESSIBLE (focus_object))
+ {
+ if (!atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (focus_object)))
+ focus_object = NULL;
+ }
+ if (focus_object)
+ obj = focus_object;
+ }
+
+ return obj;
+}
+
+static gboolean
+gail_focus_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+ GdkEvent *event;
+
+ object = g_value_get_object (param_values + 0);
+ g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
+
+ event = g_value_get_boxed (param_values + 1);
+ widget = GTK_WIDGET (object);
+
+ if (event->type == GDK_FOCUS_CHANGE)
+ {
+ if (event->focus_change.in)
+ {
+ if (GTK_IS_WINDOW (widget))
+ {
+ GtkWidget *focus_widget;
+ GtkWindow *window;
+ GtkWindowType type;
+
+ window = GTK_WINDOW (widget);
+ focus_widget = gtk_window_get_focus (window);
+ g_object_get (window, "type", &type, NULL);
+
+ if (focus_widget)
+ {
+ /*
+ * If we already have a potential focus widget set this
+ * windows's focus widget to focus_before_menu so that
+ * it will be reported when menu item is unset.
+ */
+ if (next_focus_widget)
+ {
+ if (GTK_IS_MENU_ITEM (next_focus_widget) &&
+ !focus_before_menu)
+ {
+ void *vp_focus_before_menu = &focus_before_menu;
+ focus_before_menu = focus_widget;
+ g_object_add_weak_pointer (G_OBJECT (focus_before_menu), vp_focus_before_menu);
+ }
+
+ return TRUE;
+ }
+ widget = focus_widget;
+ }
+ else if (type == GTK_WINDOW_POPUP)
+ {
+ if (GTK_IS_BIN (widget))
+ {
+ GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (GTK_IS_WIDGET (child) && gtk_widget_has_grab (child))
+ {
+ if (GTK_IS_MENU_SHELL (child))
+ {
+ if (gtk_menu_shell_get_selected_item (GTK_MENU_SHELL (child)))
+ {
+ /*
+ * We have a menu which has a menu item selected
+ * so we do not report focus on the menu.
+ */
+ return TRUE;
+ }
+ }
+ widget = child;
+ }
+ }
+ else /* popup window has no children; this edge case occurs in some custom code (OOo for instance) */
+ {
+ return TRUE;
+ }
+ }
+ else /* Widget is a non-popup toplevel with no focus children;
+ don't emit for this case either, as it's useless */
+ {
+ return TRUE;
+ }
+ }
+ }
+ else
+ {
+ if (next_focus_widget)
+ {
+ GtkWidget *toplevel;
+
+ toplevel = gtk_widget_get_toplevel (next_focus_widget);
+ if (toplevel == widget)
+ next_focus_widget = NULL;
+ }
+ /* focus out */
+ widget = NULL;
+ }
+ }
+ else
+ {
+ if (event->type == GDK_MOTION_NOTIFY && gtk_widget_has_focus (widget))
+ {
+ if (widget == focus_widget)
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+
+#ifdef GDK_WINDOWING_X11
+ /*
+ * If the focus widget is a GtkSocket without a plug
+ * then ignore the focus notification as the embedded
+ * plug will report a focus notification.
+ */
+ if (GTK_IS_SOCKET (widget) &&
+ gtk_socket_get_plug_window (GTK_SOCKET (widget)) != NULL)
+ return TRUE;
+#endif
+
+ /*
+ * The widget may not yet be visible on the screen so we wait until it is.
+ */
+ gail_focus_notify_when_idle (widget);
+ return TRUE;
+}
+
+static gboolean
+gail_select_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+
+ object = g_value_get_object (param_values + 0);
+ g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
+
+ widget = GTK_WIDGET (object);
+
+ if (!gtk_widget_get_mapped (widget))
+ {
+ g_signal_connect (widget, "map",
+ G_CALLBACK (gail_map_cb),
+ NULL);
+ }
+ else
+ gail_finish_select (widget);
+
+ return TRUE;
+}
+
+static void
+gail_finish_select (GtkWidget *widget)
+{
+ if (GTK_IS_MENU_ITEM (widget))
+ {
+ GtkMenuItem* menu_item;
+ GtkWidget *submenu;
+
+ menu_item = GTK_MENU_ITEM (widget);
+ submenu = gtk_menu_item_get_submenu (menu_item);
+ if (submenu &&
+ !gtk_widget_get_mapped (submenu))
+ {
+ /*
+ * If the submenu is not visble, wait until it is before
+ * reporting focus on the menu item.
+ */
+ gulong handler_id;
+
+ handler_id = g_signal_handler_find (submenu,
+ G_SIGNAL_MATCH_FUNC,
+ g_signal_lookup ("map",
+ GTK_TYPE_WINDOW),
+ 0,
+ NULL,
+ (gpointer) gail_map_submenu_cb,
+ NULL);
+ if (!handler_id)
+ g_signal_connect (submenu, "map",
+ G_CALLBACK (gail_map_submenu_cb),
+ NULL);
+ return;
+ }
+ /*
+ * If we are waiting to report focus on a menubar or a menu item
+ * because of a previous deselect, cancel it.
+ */
+ if (was_deselect &&
+ focus_notify_handler &&
+ next_focus_widget &&
+ (GTK_IS_MENU_BAR (next_focus_widget) ||
+ GTK_IS_MENU_ITEM (next_focus_widget)))
+ {
+ void *vp_next_focus_widget = &next_focus_widget;
+ g_source_remove (focus_notify_handler);
+ g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
+ next_focus_widget = NULL;
+ focus_notify_handler = 0;
+ was_deselect = FALSE;
+ }
+ }
+ /*
+ * If previously focused widget is not a GtkMenuItem or a GtkMenu,
+ * keep track of it so we can return to it after menubar is deactivated
+ */
+ if (focus_widget &&
+ !GTK_IS_MENU_ITEM (focus_widget) &&
+ !GTK_IS_MENU (focus_widget))
+ {
+ void *vp_focus_before_menu = &focus_before_menu;
+ focus_before_menu = focus_widget;
+ g_object_add_weak_pointer (G_OBJECT (focus_before_menu), vp_focus_before_menu);
+
+ }
+ gail_focus_notify_when_idle (widget);
+
+ return;
+}
+
+static void
+gail_map_cb (GtkWidget *widget)
+{
+ gail_finish_select (widget);
+}
+
+static void
+gail_map_submenu_cb (GtkWidget *widget)
+{
+ if (GTK_IS_MENU (widget))
+ {
+ GtkWidget *parent_menu_item;
+
+ parent_menu_item = gtk_menu_get_attach_widget (GTK_MENU (widget));
+ if (parent_menu_item)
+ gail_finish_select (parent_menu_item);
+ }
+}
+
+
+static gboolean
+gail_deselect_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+ GtkWidget *menu_shell;
+
+ object = g_value_get_object (param_values + 0);
+ g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
+
+ widget = GTK_WIDGET (object);
+
+ if (!GTK_IS_MENU_ITEM (widget))
+ return TRUE;
+
+ if (subsequent_focus_widget == widget)
+ subsequent_focus_widget = NULL;
+
+ menu_shell = gtk_widget_get_parent (widget);
+ if (GTK_IS_MENU_SHELL (menu_shell))
+ {
+ GtkWidget *parent_menu_shell;
+
+ parent_menu_shell = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (menu_shell));
+ if (parent_menu_shell)
+ {
+ GtkWidget *active_menu_item;
+
+ active_menu_item = gtk_menu_shell_get_selected_item (GTK_MENU_SHELL (parent_menu_shell));
+ if (active_menu_item)
+ {
+ gail_focus_notify_when_idle (active_menu_item);
+ }
+ }
+ else
+ {
+ if (!GTK_IS_MENU_BAR (menu_shell))
+ {
+ gail_focus_notify_when_idle (menu_shell);
+ }
+ }
+ }
+ was_deselect = TRUE;
+ return TRUE;
+}
+
+static gboolean
+gail_switch_page_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+
+ object = g_value_get_object (param_values + 0);
+ g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
+
+ widget = GTK_WIDGET (object);
+
+ if (!GTK_IS_NOTEBOOK (widget))
+ return TRUE;
+
+ if (gtk_notebook_get_current_page (GTK_NOTEBOOK (widget)) == -1)
+ return TRUE;
+
+ gail_focus_notify_when_idle (widget);
+ return TRUE;
+}
+
+static gboolean
+gail_focus_idle_handler (gpointer data)
+{
+ focus_notify_handler = 0;
+ /*
+ * The widget which was to receive focus may have been removed
+ */
+ if (!next_focus_widget)
+ {
+ if (next_focus_widget != data)
+ return FALSE;
+ }
+ else
+ {
+ void *vp_next_focus_widget = &next_focus_widget;
+ g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
+ next_focus_widget = NULL;
+ }
+
+ gail_focus_notify (data);
+
+ return FALSE;
+}
+
+static void
+gail_focus_notify (GtkWidget *widget)
+{
+ AtkObject *atk_obj;
+ gboolean transient;
+
+ if (widget != focus_widget)
+ {
+ if (focus_widget)
+ {
+ void *vp_focus_widget = &focus_widget;
+ g_object_remove_weak_pointer (G_OBJECT (focus_widget), vp_focus_widget);
+ }
+ focus_widget = widget;
+ if (focus_widget)
+ {
+ void *vp_focus_widget = &focus_widget;
+ g_object_add_weak_pointer (G_OBJECT (focus_widget), vp_focus_widget);
+ /*
+ * The UI may not have been updated yet; e.g. in gtkhtml2
+ * html_view_layout() is called in a idle handler
+ */
+ if (focus_widget == focus_before_menu)
+ {
+ void *vp_focus_before_menu = &focus_before_menu;
+ g_object_remove_weak_pointer (G_OBJECT (focus_before_menu), vp_focus_before_menu);
+ focus_before_menu = NULL;
+ }
+ }
+ gail_focus_notify_when_idle (focus_widget);
+ }
+ else
+ {
+ if (focus_widget)
+ atk_obj = gail_get_accessible_for_widget (focus_widget, &transient);
+ else
+ atk_obj = NULL;
+ /*
+ * Do not report focus on redundant object
+ */
+ if (atk_obj &&
+ (atk_object_get_role(atk_obj) != ATK_ROLE_REDUNDANT_OBJECT))
+ atk_focus_tracker_notify (atk_obj);
+ if (atk_obj && transient)
+ g_object_unref (atk_obj);
+ if (subsequent_focus_widget)
+ {
+ GtkWidget *tmp_widget = subsequent_focus_widget;
+ subsequent_focus_widget = NULL;
+ gail_focus_notify_when_idle (tmp_widget);
+ }
+ }
+}
+
+static void
+gail_focus_notify_when_idle (GtkWidget *widget)
+{
+ if (focus_notify_handler)
+ {
+ if (widget)
+ {
+ /*
+ * Ignore focus request when menu item is going to be focused.
+ * See bug #124232.
+ */
+ if (GTK_IS_MENU_ITEM (next_focus_widget) && !GTK_IS_MENU_ITEM (widget))
+ return;
+
+ if (next_focus_widget)
+ {
+ if (GTK_IS_MENU_ITEM (next_focus_widget) && GTK_IS_MENU_ITEM (widget))
+ {
+ if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (next_focus_widget)) == gtk_widget_get_parent (widget))
+ {
+ if (subsequent_focus_widget)
+ g_assert_not_reached ();
+ subsequent_focus_widget = widget;
+ return;
+ }
+ }
+ }
+ g_source_remove (focus_notify_handler);
+ if (next_focus_widget)
+ {
+ void *vp_next_focus_widget = &next_focus_widget;
+ g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
+ next_focus_widget = NULL;
+ }
+ }
+ else
+ /*
+ * Ignore if focus is being set to NULL and we are waiting to set focus
+ */
+ return;
+ }
+
+ if (widget)
+ {
+ void *vp_next_focus_widget = &next_focus_widget;
+ next_focus_widget = widget;
+ g_object_add_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
+ }
+ else
+ {
+ /*
+ * We are about to report focus as NULL so remove the weak pointer
+ * for the widget we were waiting to report focus on.
+ */
+ if (next_focus_widget)
+ {
+ void *vp_next_focus_widget = &next_focus_widget;
+ g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
+ next_focus_widget = NULL;
+ }
+ }
+
+ focus_notify_handler = gdk_threads_add_idle (gail_focus_idle_handler, widget);
+}
+
+static gboolean
+gail_deactivate_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+ GtkMenuShell *shell;
+ GtkWidget *focus = NULL;
+
+ object = g_value_get_object (param_values + 0);
+ g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
+ widget = GTK_WIDGET (object);
+
+ g_return_val_if_fail (GTK_IS_MENU_SHELL(widget), TRUE);
+ shell = GTK_MENU_SHELL(widget);
+ if (! gtk_menu_shell_get_parent_shell (shell))
+ focus = focus_before_menu;
+
+ /*
+ * If we are waiting to report focus on a menubar or a menu item
+ * because of a previous deselect, cancel it.
+ */
+ if (was_deselect &&
+ focus_notify_handler &&
+ next_focus_widget &&
+ (GTK_IS_MENU_BAR (next_focus_widget) ||
+ GTK_IS_MENU_ITEM (next_focus_widget)))
+ {
+ void *vp_next_focus_widget = &next_focus_widget;
+ g_source_remove (focus_notify_handler);
+ g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
+ next_focus_widget = NULL;
+ focus_notify_handler = 0;
+ was_deselect = FALSE;
+ }
+ gail_focus_notify_when_idle (focus);
+
+ return TRUE;
+}
+
+static void
+gail_focus_tracker_init (void)
+{
+ static gboolean emission_hooks_added = FALSE;
+
+ if (!emission_hooks_added)
+ {
+ /*
+ * We cannot be sure that the classes exist so we make sure that they do.
+ */
+ g_type_class_ref (GTK_TYPE_WIDGET);
+ g_type_class_ref (GTK_TYPE_MENU_ITEM);
+ g_type_class_ref (GTK_TYPE_MENU_SHELL);
+ g_type_class_ref (GTK_TYPE_NOTEBOOK);
+
+ /*
+ * We listen for event_after signal and then check that the
+ * event was a focus in event so we get called after the event.
+ */
+ g_signal_add_emission_hook (
+ g_signal_lookup ("event-after", GTK_TYPE_WIDGET), 0,
+ gail_focus_watcher, NULL, (GDestroyNotify) NULL);
+ /*
+ * A "select" signal is emitted when arrow key is used to
+ * move to a list item in the popup window of a GtkCombo or
+ * a menu item in a menu.
+ */
+ g_signal_add_emission_hook (
+ g_signal_lookup ("select", GTK_TYPE_MENU_ITEM), 0,
+ gail_select_watcher, NULL, (GDestroyNotify) NULL);
+
+ /*
+ * A "deselect" signal is emitted when arrow key is used to
+ * move from a menu item in a menu to the parent menu.
+ */
+ g_signal_add_emission_hook (
+ g_signal_lookup ("deselect", GTK_TYPE_MENU_ITEM), 0,
+ gail_deselect_watcher, NULL, (GDestroyNotify) NULL);
+
+ /*
+ * We listen for deactivate signals on menushells to determine
+ * when the "focus" has left the menus.
+ */
+ g_signal_add_emission_hook (
+ g_signal_lookup ("deactivate", GTK_TYPE_MENU_SHELL), 0,
+ gail_deactivate_watcher, NULL, (GDestroyNotify) NULL);
+
+ /*
+ * We listen for "switch-page" signal on a GtkNotebook to notify
+ * when page has changed because of clicking on a notebook tab.
+ */
+ g_signal_add_emission_hook (
+ g_signal_lookup ("switch-page", GTK_TYPE_NOTEBOOK), 0,
+ gail_switch_page_watcher, NULL, (GDestroyNotify) NULL);
+ emission_hooks_added = TRUE;
+ }
+}
+
+static void
+gail_focus_object_destroyed (gpointer data)
+{
+ GObject *obj;
+
+ obj = G_OBJECT (data);
+ g_object_set_qdata (obj, quark_focus_object, NULL);
+ g_object_unref (obj);
+}
+
+static void
+gail_focus_tracker (AtkObject *focus_object)
+{
+ /*
+ * Do not report focus on redundant object
+ */
+ if (focus_object &&
+ (atk_object_get_role(focus_object) != ATK_ROLE_REDUNDANT_OBJECT))
+ {
+ AtkObject *old_focus_object;
+
+ if (!GTK_IS_ACCESSIBLE (focus_object))
+ {
+ AtkObject *parent;
+
+ parent = focus_object;
+ while (1)
+ {
+ parent = atk_object_get_parent (parent);
+ if (parent == NULL)
+ break;
+ if (GTK_IS_ACCESSIBLE (parent))
+ break;
+ }
+
+ if (parent)
+ {
+ gail_set_focus_object (focus_object, parent);
+ }
+ }
+ else
+ {
+ old_focus_object = g_object_get_qdata (G_OBJECT (focus_object), quark_focus_object);
+ if (old_focus_object)
+ {
+ g_object_weak_unref (G_OBJECT (old_focus_object),
+ (GWeakNotify) gail_focus_object_destroyed,
+ focus_object);
+ g_object_set_qdata (G_OBJECT (focus_object), quark_focus_object, NULL);
+ g_object_unref (G_OBJECT (focus_object));
+ }
+ }
+ }
+}
+
+static void
+gail_set_focus_widget (GtkWidget *focus_widget,
+ GtkWidget *widget)
+{
+ AtkObject *focus_obj;
+ AtkObject *obj;
+
+ focus_obj = gtk_widget_get_accessible (focus_widget);
+ obj = gtk_widget_get_accessible (widget);
+ gail_set_focus_object (focus_obj, obj);
+}
+
+static void
+gail_set_focus_object (AtkObject *focus_obj,
+ AtkObject *obj)
+{
+ AtkObject *old_focus_obj;
+
+ old_focus_obj = g_object_get_qdata (G_OBJECT (obj), quark_focus_object);
+ if (old_focus_obj != obj)
+ {
+ if (old_focus_obj)
+ g_object_weak_unref (G_OBJECT (old_focus_obj),
+ (GWeakNotify) gail_focus_object_destroyed,
+ obj);
+ else
+ /*
+ * We call g_object_ref as if obj is destroyed
+ * while the weak reference exists then destroying the
+ * focus_obj would cause gail_focus_object_destroyed to be
+ * called when obj is not a valid GObject.
+ */
+ g_object_ref (obj);
+
+ g_object_weak_ref (G_OBJECT (focus_obj),
+ (GWeakNotify) gail_focus_object_destroyed,
+ obj);
+ g_object_set_qdata (G_OBJECT (obj), quark_focus_object, focus_obj);
+ }
+}
+
+/*
+ * These exported symbols are hooked by gnome-program
+ * to provide automatic module initialization and shutdown.
+ */
+extern void gnome_accessibility_module_init (void);
+extern void gnome_accessibility_module_shutdown (void);
+
+static int gail_initialized = FALSE;
+
+static void
+gail_accessibility_module_init (void)
+{
+ const char *env_a_t_support;
+ gboolean a_t_support = FALSE;
+
+ if (gail_initialized)
+ {
+ return;
+ }
+ gail_initialized = TRUE;
+ quark_focus_object = g_quark_from_static_string ("gail-focus-object");
+
+ env_a_t_support = g_getenv (GNOME_ACCESSIBILITY_ENV);
+
+ if (env_a_t_support)
+ a_t_support = atoi (env_a_t_support);
+ if (a_t_support)
+ fprintf (stderr, "GTK Accessibility Module initialized\n");
+
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WIDGET, gail_widget);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CONTAINER, gail_container);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_BUTTON, gail_button);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_LINK_BUTTON, gail_link_button);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU_ITEM, gail_menu_item);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_TOGGLE_BUTTON, gail_toggle_button);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_IMAGE, gail_image);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_TEXT_VIEW, gail_text_view);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_COMBO_BOX, gail_combo_box);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_ENTRY, gail_entry);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU_BAR, gail_menu_shell);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU, gail_menu);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WINDOW, gail_window);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_RANGE, gail_range);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCALE, gail_scale);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCALE_BUTTON, gail_scale_button);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_LABEL, gail_label);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_STATUSBAR, gail_statusbar);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_NOTEBOOK, gail_notebook);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CALENDAR, gail_calendar);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_PROGRESS_BAR, gail_progress_bar);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SPIN_BUTTON, gail_spin_button);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_TREE_VIEW, gail_tree_view);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_FRAME, gail_frame);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_TEXT, gail_text_cell);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_TOGGLE, gail_boolean_cell);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_PIXBUF, gail_image_cell);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER, gail_renderer_cell);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_RADIO_BUTTON, gail_radio_button);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_ARROW, gail_arrow);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SEPARATOR, gail_separator);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_BOX, gail_box);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCROLLED_WINDOW, gail_scrolled_window);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_PANED, gail_paned);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCROLLBAR, gail_scrollbar);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CHECK_MENU_ITEM, gail_check_menu_item);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_RADIO_MENU_ITEM, gail_radio_menu_item);
+ GAIL_WIDGET_SET_FACTORY (GTK_TYPE_EXPANDER, gail_expander);
+
+ atk_focus_tracker_init (gail_focus_tracker_init);
+ focus_tracker_id = atk_add_focus_tracker (gail_focus_tracker);
+
+ /* Initialize the GailUtility class */
+ g_type_class_unref (g_type_class_ref (GAIL_TYPE_UTIL));
+ g_type_class_unref (g_type_class_ref (GAIL_TYPE_MISC));
+}
+
+/**
+ * gnome_accessibility_module_init:
+ * @void:
+ *
+ * This method is invoked by name from libgnome's
+ * gnome-program.c to activate accessibility support.
+ **/
+void
+gnome_accessibility_module_init (void)
+{
+ gail_accessibility_module_init ();
+}
+
+/**
+ * gnome_accessibility_module_shutdown:
+ * @void:
+ *
+ * This method is invoked by name from libgnome's
+ * gnome-program.c to de-activate accessibility support.
+ **/
+void
+gnome_accessibility_module_shutdown (void)
+{
+ if (!gail_initialized)
+ {
+ return;
+ }
+ gail_initialized = FALSE;
+ atk_remove_focus_tracker (focus_tracker_id);
+
+ fprintf (stderr, "GTK Accessibility Module shutdown\n");
+
+ /* FIXME: de-register the factory types so we can unload ? */
+}
+
+int
+gtk_module_init (gint *argc, char** argv[])
+{
+ const char* env_no_gail;
+ gboolean no_gail = FALSE;
+
+ env_no_gail = g_getenv (NO_GAIL_ENV);
+ if (env_no_gail)
+ no_gail = atoi (env_no_gail);
+
+ if (no_gail)
+ return 0;
+
+ gail_accessibility_module_init ();
+
+ return 0;
+}
+
+const char *
+g_module_check_init (GModule *module)
+{
+ g_module_make_resident (module);
+
+ return NULL;
+}
+
--- /dev/null
+#include "gailadjustment.h"
+#include "gailarrow.h"
+#include "gailbooleancell.h"
+#include "gailbox.h"
+#include "gailbutton.h"
+#include "gailcalendar.h"
+#include "gailcell.h"
+#include "gailcheckmenuitem.h"
+#include "gailcombobox.h"
+#include "gailcontainer.h"
+#include "gailcontainercell.h"
+#include "gailentry.h"
+#include "gailexpander.h"
+#include "gailframe.h"
+#include "gailimage.h"
+#include "gailimagecell.h"
+#include "gaillabel.h"
+#include "gaillinkbutton.h"
+#include "gailmenu.h"
+#include "gailmenushell.h"
+#include "gailmenuitem.h"
+#include "gailnotebook.h"
+#include "gailpaned.h"
+#include "gailprogressbar.h"
+#include "gailradiobutton.h"
+#include "gailradiomenuitem.h"
+#include "gailrenderercell.h"
+#include "gailrange.h"
+#include "gailscale.h"
+#include "gailscalebutton.h"
+#include "gailscrollbar.h"
+#include "gailscrolledwindow.h"
+#include "gailseparator.h"
+#include "gailspinbutton.h"
+#include "gailstatusbar.h"
+#include "gailtextcell.h"
+#include "gailtextview.h"
+#include "gailtogglebutton.h"
+#include "gailtoplevel.h"
+#include "gailtreeview.h"
+#include "gailutil.h"
+#include "gailwidget.h"
+#include "gailwindow.h"
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailadjustment.h"
+
+static void gail_adjustment_class_init (GailAdjustmentClass *klass);
+
+static void gail_adjustment_init (GailAdjustment *adjustment);
+
+static void gail_adjustment_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static void atk_value_interface_init (AtkValueIface *iface);
+
+static void gail_adjustment_get_current_value (AtkValue *obj,
+ GValue *value);
+static void gail_adjustment_get_maximum_value (AtkValue *obj,
+ GValue *value);
+static void gail_adjustment_get_minimum_value (AtkValue *obj,
+ GValue *value);
+static void gail_adjustment_get_minimum_increment (AtkValue *obj,
+ GValue *value);
+static gboolean gail_adjustment_set_current_value (AtkValue *obj,
+ const GValue *value);
+
+G_DEFINE_TYPE_WITH_CODE (GailAdjustment, gail_adjustment, ATK_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
+
+static void
+gail_adjustment_class_init (GailAdjustmentClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->initialize = gail_adjustment_real_initialize;
+}
+
+static void
+gail_adjustment_init (GailAdjustment *adjustment)
+{
+}
+
+AtkObject*
+gail_adjustment_new (GtkAdjustment *adjustment)
+{
+ GObject *object;
+ AtkObject *atk_object;
+
+ g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), NULL);
+
+ object = g_object_new (GAIL_TYPE_ADJUSTMENT, NULL);
+
+ atk_object = ATK_OBJECT (object);
+ atk_object_initialize (atk_object, adjustment);
+
+ return atk_object;
+}
+
+static void
+gail_adjustment_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkAdjustment *adjustment;
+ GailAdjustment *gail_adjustment;
+
+ ATK_OBJECT_CLASS (gail_adjustment_parent_class)->initialize (obj, data);
+
+ adjustment = GTK_ADJUSTMENT (data);
+
+ obj->role = ATK_ROLE_UNKNOWN;
+ gail_adjustment = GAIL_ADJUSTMENT (obj);
+ gail_adjustment->adjustment = adjustment;
+
+ g_object_add_weak_pointer (G_OBJECT (adjustment),
+ (gpointer *) &gail_adjustment->adjustment);
+}
+
+static void
+atk_value_interface_init (AtkValueIface *iface)
+{
+ iface->get_current_value = gail_adjustment_get_current_value;
+ iface->get_maximum_value = gail_adjustment_get_maximum_value;
+ iface->get_minimum_value = gail_adjustment_get_minimum_value;
+ iface->get_minimum_increment = gail_adjustment_get_minimum_increment;
+ iface->set_current_value = gail_adjustment_set_current_value;
+}
+
+static void
+gail_adjustment_get_current_value (AtkValue *obj,
+ GValue *value)
+{
+ GtkAdjustment* adjustment;
+ gdouble current_value;
+
+ adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
+ if (adjustment == NULL)
+ {
+ /* State is defunct */
+ return;
+ }
+
+ current_value = gtk_adjustment_get_value (adjustment);
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value,current_value);
+}
+
+static void
+gail_adjustment_get_maximum_value (AtkValue *obj,
+ GValue *value)
+{
+ GtkAdjustment* adjustment;
+ gdouble maximum_value;
+
+ adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
+ if (adjustment == NULL)
+ {
+ /* State is defunct */
+ return;
+ }
+
+ maximum_value = gtk_adjustment_get_upper (adjustment);
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, maximum_value);
+}
+
+static void
+gail_adjustment_get_minimum_value (AtkValue *obj,
+ GValue *value)
+{
+ GtkAdjustment* adjustment;
+ gdouble minimum_value;
+
+ adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
+ if (adjustment == NULL)
+ {
+ /* State is defunct */
+ return;
+ }
+
+ minimum_value = gtk_adjustment_get_lower (adjustment);
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, minimum_value);
+}
+
+static void
+gail_adjustment_get_minimum_increment (AtkValue *obj,
+ GValue *value)
+{
+ GtkAdjustment* adjustment;
+ gdouble minimum_increment;
+
+ adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
+ if (adjustment == NULL)
+ {
+ /* State is defunct */
+ return;
+ }
+
+ if (gtk_adjustment_get_step_increment (adjustment) != 0 &&
+ gtk_adjustment_get_page_increment (adjustment) != 0)
+ {
+ if (ABS (gtk_adjustment_get_step_increment (adjustment)) < ABS (gtk_adjustment_get_page_increment (adjustment)))
+ minimum_increment = gtk_adjustment_get_step_increment (adjustment);
+ else
+ minimum_increment = gtk_adjustment_get_page_increment (adjustment);
+ }
+ else if (gtk_adjustment_get_step_increment (adjustment) == 0 &&
+ gtk_adjustment_get_page_increment (adjustment) == 0)
+ {
+ minimum_increment = 0;
+ }
+ else if (gtk_adjustment_get_step_increment (adjustment) == 0)
+ {
+ minimum_increment = gtk_adjustment_get_page_increment (adjustment);
+ }
+ else
+ {
+ minimum_increment = gtk_adjustment_get_step_increment (adjustment);
+ }
+
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, minimum_increment);
+}
+
+static gboolean
+gail_adjustment_set_current_value (AtkValue *obj,
+ const GValue *value)
+{
+ if (G_VALUE_HOLDS_DOUBLE (value))
+ {
+ GtkAdjustment* adjustment;
+ gdouble new_value;
+
+ adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
+ if (adjustment == NULL)
+ {
+ /* State is defunct */
+ return FALSE;
+ }
+ new_value = g_value_get_double (value);
+ gtk_adjustment_set_value (adjustment, new_value);
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_ADJUSTMENT_H__
+#define __GAIL_ADJUSTMENT_H__
+
+#include <atk/atk.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_ADJUSTMENT (gail_adjustment_get_type ())
+#define GAIL_ADJUSTMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_ADJUSTMENT, GailAdjustment))
+#define GAIL_ADJUSTMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_ADJUSTMENT, GailAdjustmentClass))
+#define GAIL_IS_ADJUSTMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_ADJUSTMENT))
+#define GAIL_IS_ADJUSTMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_ADJUSTMENT))
+#define GAIL_ADJUSTMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_ADJUSTMENT, GailAdjustmentClass))
+
+typedef struct _GailAdjustment GailAdjustment;
+typedef struct _GailAdjustmentClass GailAdjustmentClass;
+
+struct _GailAdjustment
+{
+ AtkObject parent;
+
+ GtkAdjustment *adjustment;
+};
+
+GType gail_adjustment_get_type (void);
+
+struct _GailAdjustmentClass
+{
+ AtkObjectClass parent_class;
+};
+
+AtkObject *gail_adjustment_new (GtkAdjustment *adjustment);
+
+G_END_DECLS
+
+#endif /* __GAIL_ADJUSTMENT_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailarrow.h"
+
+static void gail_arrow_class_init (GailArrowClass *klass);
+static void gail_arrow_init (GailArrow *arrow);
+static void gail_arrow_initialize (AtkObject *accessible,
+ gpointer data);
+
+/* AtkImage */
+static void atk_image_interface_init (AtkImageIface *iface);
+static const gchar* gail_arrow_get_image_description
+ (AtkImage *obj);
+static gboolean gail_arrow_set_image_description
+ (AtkImage *obj,
+ const gchar *description);
+static void gail_arrow_finalize (GObject *object);
+
+G_DEFINE_TYPE_WITH_CODE (GailArrow, gail_arrow, GAIL_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init))
+
+static void
+gail_arrow_class_init (GailArrowClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
+
+ atk_object_class->initialize = gail_arrow_initialize;
+
+ gobject_class->finalize = gail_arrow_finalize;
+}
+
+static void
+gail_arrow_init (GailArrow *arrow)
+{
+ arrow->image_description = NULL;
+}
+
+static void
+gail_arrow_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_arrow_parent_class)->initialize (accessible, data);
+
+ accessible->role = ATK_ROLE_ICON;
+}
+
+static void
+atk_image_interface_init (AtkImageIface *iface)
+{
+ iface->get_image_description = gail_arrow_get_image_description;
+ iface->set_image_description = gail_arrow_set_image_description;
+}
+
+static const gchar*
+gail_arrow_get_image_description (AtkImage *obj)
+{
+ GailArrow* arrow;
+
+ g_return_val_if_fail(GAIL_IS_ARROW(obj), NULL);
+
+ arrow = GAIL_ARROW (obj);
+
+ return arrow->image_description;
+}
+
+static gboolean
+gail_arrow_set_image_description (AtkImage *obj,
+ const gchar *description)
+{
+ GailArrow* arrow;
+
+ g_return_val_if_fail(GAIL_IS_ARROW(obj), FALSE);
+
+ arrow = GAIL_ARROW (obj);
+ g_free (arrow->image_description);
+
+ arrow->image_description = g_strdup (description);
+
+ return TRUE;
+
+}
+
+/*
+ * static void
+ * gail_arrow_get_image_size (AtkImage *obj,
+ * gint *height,
+ * gint *width)
+ *
+ * We dont implement this function for GailArrow as gtk hardcodes the size
+ * of the arrow to be 7x5 and it is not possible to query this.
+ */
+
+static void
+gail_arrow_finalize (GObject *object)
+{
+ GailArrow *arrow = GAIL_ARROW (object);
+
+ g_free (arrow->image_description);
+ G_OBJECT_CLASS (gail_arrow_parent_class)->finalize (object);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_ARROW_H__
+#define __GAIL_ARROW_H__
+
+#include "gailwidget.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_ARROW (gail_arrow_get_type ())
+#define GAIL_ARROW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_ARROW, GailArrow))
+#define GAIL_ARROW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_ARROW, GailArrowClass))
+#define GAIL_IS_ARROW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_ARROW))
+#define GAIL_IS_ARROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_ARROW))
+#define GAIL_ARROW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_ARROW, GailArrowClass))
+
+typedef struct _GailArrow GailArrow;
+typedef struct _GailArrowClass GailArrowClass;
+
+struct _GailArrow
+{
+ GailWidget parent;
+
+ gchar* image_description;
+};
+
+GType gail_arrow_get_type (void);
+
+struct _GailArrowClass
+{
+ GailWidgetClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_ARROW_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailbooleancell.h"
+
+static void gail_boolean_cell_class_init (GailBooleanCellClass *klass);
+static void gail_boolean_cell_init (GailBooleanCell *cell);
+/* Misc */
+
+static gboolean gail_boolean_cell_update_cache (GailRendererCell *cell,
+ gboolean emit_change_signal);
+
+gchar *gail_boolean_cell_property_list[] = {
+ "active",
+ "radio",
+ "sensitive",
+ NULL
+};
+
+G_DEFINE_TYPE (GailBooleanCell, gail_boolean_cell, GAIL_TYPE_RENDERER_CELL)
+
+static void
+gail_boolean_cell_class_init (GailBooleanCellClass *klass)
+{
+ GailRendererCellClass *renderer_cell_class = GAIL_RENDERER_CELL_CLASS (klass);
+
+ renderer_cell_class->update_cache = gail_boolean_cell_update_cache;
+ renderer_cell_class->property_list = gail_boolean_cell_property_list;
+}
+
+static void
+gail_boolean_cell_init (GailBooleanCell *cell)
+{
+}
+
+AtkObject*
+gail_boolean_cell_new (void)
+{
+ GObject *object;
+ AtkObject *atk_object;
+ GailRendererCell *cell;
+ GailBooleanCell *boolean_cell;
+
+ object = g_object_new (GAIL_TYPE_BOOLEAN_CELL, NULL);
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ atk_object = ATK_OBJECT (object);
+ atk_object->role = ATK_ROLE_TABLE_CELL;
+
+ cell = GAIL_RENDERER_CELL(object);
+ boolean_cell = GAIL_BOOLEAN_CELL(object);
+
+ cell->renderer = gtk_cell_renderer_toggle_new ();
+ g_object_ref_sink (cell->renderer);
+ boolean_cell->cell_value = FALSE;
+ boolean_cell->cell_sensitive = TRUE;
+ return atk_object;
+}
+
+static gboolean
+gail_boolean_cell_update_cache (GailRendererCell *cell,
+ gboolean emit_change_signal)
+{
+ GailBooleanCell *boolean_cell = GAIL_BOOLEAN_CELL (cell);
+ gboolean rv = FALSE;
+ gboolean new_boolean;
+ gboolean new_sensitive;
+
+ g_object_get (G_OBJECT(cell->renderer), "active", &new_boolean,
+ "sensitive", &new_sensitive, NULL);
+
+ if (boolean_cell->cell_value != new_boolean)
+ {
+ rv = TRUE;
+ boolean_cell->cell_value = !(boolean_cell->cell_value);
+
+ /* Update cell's state */
+
+ if (new_boolean)
+ gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_CHECKED, emit_change_signal);
+ else
+ gail_cell_remove_state (GAIL_CELL (cell), ATK_STATE_CHECKED, emit_change_signal);
+ }
+
+ if (boolean_cell->cell_sensitive != new_sensitive)
+ {
+ rv = TRUE;
+ boolean_cell->cell_sensitive = !(boolean_cell->cell_sensitive);
+
+ /* Update cell's state */
+
+ if (new_sensitive)
+ gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_SENSITIVE, emit_change_signal);
+ else
+ gail_cell_remove_state (GAIL_CELL (cell), ATK_STATE_SENSITIVE, emit_change_signal);
+ }
+
+ return rv;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_BOOLEAN_CELL_H__
+#define __GAIL_BOOLEAN_CELL_H__
+
+#include <atk/atk.h>
+#include "gailrenderercell.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_BOOLEAN_CELL (gail_boolean_cell_get_type ())
+#define GAIL_BOOLEAN_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_BOOLEAN_CELL, GailBooleanCell))
+#define GAIL_BOOLEAN_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_BOOLEAN_CELL, GailBooleanCellClass))
+#define GAIL_IS_BOOLEAN_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_BOOLEAN_CELL))
+#define GAIL_IS_BOOLEAN_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_BOOLEAN_CELL))
+#define GAIL_BOOLEAN_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_BOOLEAN_CELL, GailBooleanCellClass))
+
+typedef struct _GailBooleanCell GailBooleanCell;
+typedef struct _GailBooleanCellClass GailBooleanCellClass;
+
+struct _GailBooleanCell
+{
+ GailRendererCell parent;
+ gboolean cell_value;
+ gboolean cell_sensitive;
+};
+
+ GType gail_boolean_cell_get_type (void);
+
+struct _GailBooleanCellClass
+{
+ GailRendererCellClass parent_class;
+};
+
+AtkObject *gail_boolean_cell_new (void);
+
+G_END_DECLS
+
+#endif /* __GAIL_TREE_VIEW_BOOLEAN_CELL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailbox.h"
+
+static void gail_box_class_init (GailBoxClass *klass);
+static void gail_box_init (GailBox *box);
+static void gail_box_initialize (AtkObject *accessible,
+ gpointer data);
+
+G_DEFINE_TYPE (GailBox, gail_box, GAIL_TYPE_CONTAINER)
+
+static void
+gail_box_class_init (GailBoxClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->initialize = gail_box_initialize;
+}
+
+static void
+gail_box_init (GailBox *box)
+{
+}
+
+static void
+gail_box_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_box_parent_class)->initialize (accessible, data);
+
+ accessible->role = ATK_ROLE_FILLER;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_BOX_H__
+#define __GAIL_BOX_H__
+
+#include "gailcontainer.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_BOX (gail_box_get_type ())
+#define GAIL_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_BOX, GailBox))
+#define GAIL_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_BOX, GailBoxClass))
+#define GAIL_IS_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_BOX))
+#define GAIL_IS_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_BOX))
+#define GAIL_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_BOX, GailBoxClass))
+
+typedef struct _GailBox GailBox;
+typedef struct _GailBoxClass GailBoxClass;
+
+struct _GailBox
+{
+ GailContainer parent;
+};
+
+GType gail_box_get_type (void);
+
+struct _GailBoxClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_BOX_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "gailbutton.h"
+#include <libgail-util/gailmisc.h>
+
+#define GAIL_BUTTON_ATTACHED_MENUS "gtk-attached-menus"
+
+static void gail_button_class_init (GailButtonClass *klass);
+static void gail_button_init (GailButton *button);
+
+static const gchar* gail_button_get_name (AtkObject *obj);
+static gint gail_button_get_n_children (AtkObject *obj);
+static AtkObject* gail_button_ref_child (AtkObject *obj,
+ gint i);
+static AtkStateSet* gail_button_ref_state_set (AtkObject *obj);
+static void gail_button_notify_label_gtk (GObject *obj,
+ GParamSpec *pspec,
+ gpointer data);
+static void gail_button_label_map_gtk (GtkWidget *widget,
+ gpointer data);
+
+static void gail_button_real_initialize (AtkObject *obj,
+ gpointer data);
+static void gail_button_finalize (GObject *object);
+static void gail_button_init_textutil (GailButton *button,
+ GtkWidget *label);
+
+static void gail_button_pressed_enter_handler (GtkWidget *widget);
+static void gail_button_released_leave_handler (GtkWidget *widget);
+static gint gail_button_real_add_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data);
+
+
+static void atk_action_interface_init (AtkActionIface *iface);
+static gboolean gail_button_do_action (AtkAction *action,
+ gint i);
+static gboolean idle_do_action (gpointer data);
+static gint gail_button_get_n_actions (AtkAction *action);
+static const gchar* gail_button_get_description(AtkAction *action,
+ gint i);
+static const gchar* gail_button_get_keybinding (AtkAction *action,
+ gint i);
+static const gchar* gail_button_action_get_name(AtkAction *action,
+ gint i);
+static gboolean gail_button_set_description(AtkAction *action,
+ gint i,
+ const gchar *desc);
+static void gail_button_notify_label_weak_ref (gpointer data,
+ GObject *obj);
+static void gail_button_notify_weak_ref (gpointer data,
+ GObject *obj);
+
+
+/* AtkImage.h */
+static void atk_image_interface_init (AtkImageIface *iface);
+static const gchar* gail_button_get_image_description
+ (AtkImage *image);
+static void gail_button_get_image_position
+ (AtkImage *image,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type);
+static void gail_button_get_image_size (AtkImage *image,
+ gint *width,
+ gint *height);
+static gboolean gail_button_set_image_description
+ (AtkImage *image,
+ const gchar *description);
+
+/* atktext.h */
+static void atk_text_interface_init (AtkTextIface *iface);
+
+static gchar* gail_button_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gunichar gail_button_get_character_at_offset(AtkText *text,
+ gint offset);
+static gchar* gail_button_get_text_before_offset(AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_button_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_button_get_text_after_offset(AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gint gail_button_get_character_count (AtkText *text);
+static void gail_button_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static gint gail_button_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static AtkAttributeSet* gail_button_get_run_attributes
+ (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet* gail_button_get_default_attributes
+ (AtkText *text);
+static GtkImage* get_image_from_button (GtkWidget *button);
+static GtkWidget* get_label_from_button (GtkWidget *button,
+ gint index,
+ gboolean allow_many);
+static gint get_n_labels_from_button (GtkWidget *button);
+static void set_role_for_button (AtkObject *accessible,
+ GtkWidget *button);
+
+static gint get_n_attached_menus (GtkWidget *widget);
+static GtkWidget* get_nth_attached_menu (GtkWidget *widget,
+ gint index);
+
+G_DEFINE_TYPE_WITH_CODE (GailButton, gail_button, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
+
+static void
+gail_button_class_init (GailButtonClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailContainerClass *container_class;
+
+ container_class = (GailContainerClass*)klass;
+
+ gobject_class->finalize = gail_button_finalize;
+
+ class->get_name = gail_button_get_name;
+ class->get_n_children = gail_button_get_n_children;
+ class->ref_child = gail_button_ref_child;
+ class->ref_state_set = gail_button_ref_state_set;
+ class->initialize = gail_button_real_initialize;
+
+ container_class->add_gtk = gail_button_real_add_gtk;
+ container_class->remove_gtk = NULL;
+}
+
+static void
+gail_button_init (GailButton *button)
+{
+ button->click_description = NULL;
+ button->press_description = NULL;
+ button->release_description = NULL;
+ button->click_keybinding = NULL;
+ button->action_queue = NULL;
+ button->action_idle_handler = 0;
+ button->textutil = NULL;
+}
+
+static const gchar*
+gail_button_get_name (AtkObject *obj)
+{
+ const gchar* name = NULL;
+
+ g_return_val_if_fail (GAIL_IS_BUTTON (obj), NULL);
+
+ name = ATK_OBJECT_CLASS (gail_button_parent_class)->get_name (obj);
+ if (name == NULL)
+ {
+ /*
+ * Get the text on the label
+ */
+ GtkWidget *widget;
+ GtkWidget *child;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ g_return_val_if_fail (GTK_IS_BUTTON (widget), NULL);
+
+ child = get_label_from_button (widget, 0, FALSE);
+ if (GTK_IS_LABEL (child))
+ name = gtk_label_get_text (GTK_LABEL (child));
+ else
+ {
+ GtkImage *image;
+
+ image = get_image_from_button (widget);
+ if (GTK_IS_IMAGE (image))
+ {
+ AtkObject *atk_obj;
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (image));
+ name = atk_object_get_name (atk_obj);
+ }
+ }
+ }
+ return name;
+}
+
+/*
+ * A DownArrow in a GtkToggltButton whose parent is not a ColorCombo
+ * has press as default action.
+ */
+static gboolean
+gail_button_is_default_press (GtkWidget *widget)
+{
+ GtkArrowType arrow_type;
+ GtkWidget *child;
+ GtkWidget *parent;
+ gboolean ret = FALSE;
+ const gchar *parent_type_name;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (GTK_IS_ARROW (child))
+ {
+ g_object_get (child,
+ "arrow_type", &arrow_type,
+ NULL);
+
+ if (arrow_type == GTK_ARROW_DOWN)
+ {
+ parent = gtk_widget_get_parent (widget);
+ if (parent)
+ {
+ parent_type_name = g_type_name (G_OBJECT_TYPE (parent));
+ if (g_strcmp0 (parent_type_name, "ColorCombo"))
+ return TRUE;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static void
+gail_button_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GailButton *button = GAIL_BUTTON (obj);
+ GtkWidget *label;
+ GtkWidget *widget;
+
+ ATK_OBJECT_CLASS (gail_button_parent_class)->initialize (obj, data);
+
+ button->state = GTK_STATE_NORMAL;
+
+ g_signal_connect (data,
+ "pressed",
+ G_CALLBACK (gail_button_pressed_enter_handler),
+ NULL);
+ g_signal_connect (data,
+ "enter",
+ G_CALLBACK (gail_button_pressed_enter_handler),
+ NULL);
+ g_signal_connect (data,
+ "released",
+ G_CALLBACK (gail_button_released_leave_handler),
+ NULL);
+ g_signal_connect (data,
+ "leave",
+ G_CALLBACK (gail_button_released_leave_handler),
+ NULL);
+
+
+ widget = GTK_WIDGET (data);
+ label = get_label_from_button (widget, 0, FALSE);
+ if (GTK_IS_LABEL (label))
+ {
+ if (gtk_widget_get_mapped (label))
+ gail_button_init_textutil (button, label);
+ else
+ g_signal_connect (label,
+ "map",
+ G_CALLBACK (gail_button_label_map_gtk),
+ button);
+ }
+ button->default_is_press = gail_button_is_default_press (widget);
+
+ set_role_for_button (obj, data);
+}
+
+static void
+gail_button_label_map_gtk (GtkWidget *widget,
+ gpointer data)
+{
+ GailButton *button;
+
+ button = GAIL_BUTTON (data);
+ gail_button_init_textutil (button, widget);
+}
+
+static void
+gail_button_notify_label_gtk (GObject *obj,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ AtkObject* atk_obj = ATK_OBJECT (data);
+ GtkLabel *label;
+ GailButton *gail_button;
+
+ if (strcmp (pspec->name, "label") == 0)
+ {
+ const gchar* label_text;
+
+ label = GTK_LABEL (obj);
+
+ label_text = gtk_label_get_text (label);
+
+ gail_button = GAIL_BUTTON (atk_obj);
+ gail_text_util_text_setup (gail_button->textutil, label_text);
+
+ if (atk_obj->name == NULL)
+ {
+ /*
+ * The label has changed so notify a change in accessible-name
+ */
+ g_object_notify (G_OBJECT (atk_obj), "accessible-name");
+ }
+ /*
+ * The label is the only property which can be changed
+ */
+ g_signal_emit_by_name (atk_obj, "visible_data_changed");
+ }
+}
+
+static void
+gail_button_notify_weak_ref (gpointer data, GObject* obj)
+{
+ GtkLabel *label = NULL;
+
+ AtkObject* atk_obj = ATK_OBJECT (obj);
+ if (data && GTK_IS_WIDGET (data))
+ {
+ label = GTK_LABEL (data);
+ if (label)
+ {
+ g_signal_handlers_disconnect_by_func (label,
+ (GCallback) gail_button_notify_label_gtk,
+ GAIL_BUTTON (atk_obj));
+ g_object_weak_unref (G_OBJECT (label),
+ gail_button_notify_label_weak_ref,
+ GAIL_BUTTON (atk_obj));
+ }
+ }
+}
+
+static void
+gail_button_notify_label_weak_ref (gpointer data, GObject* obj)
+{
+ GtkLabel *label = NULL;
+ GailButton *button = NULL;
+
+ label = GTK_LABEL (obj);
+ if (data && GAIL_IS_BUTTON (data))
+ {
+ button = GAIL_BUTTON (ATK_OBJECT (data));
+ if (button)
+ g_object_weak_unref (G_OBJECT (button), gail_button_notify_weak_ref,
+ label);
+ }
+}
+
+
+static void
+gail_button_init_textutil (GailButton *button,
+ GtkWidget *label)
+{
+ const gchar *label_text;
+
+ if (button->textutil)
+ g_object_unref (button->textutil);
+ button->textutil = gail_text_util_new ();
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ gail_text_util_text_setup (button->textutil, label_text);
+ g_object_weak_ref (G_OBJECT (button),
+ gail_button_notify_weak_ref, label);
+ g_object_weak_ref (G_OBJECT (label),
+ gail_button_notify_label_weak_ref, button);
+ g_signal_connect (label,
+ "notify",
+ (GCallback) gail_button_notify_label_gtk,
+ button);
+}
+
+static gint
+gail_button_real_add_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data)
+{
+ GtkLabel *label;
+ GailButton *button;
+
+ if (GTK_IS_LABEL (widget))
+ {
+ const gchar* label_text;
+
+ label = GTK_LABEL (widget);
+
+
+ button = GAIL_BUTTON (data);
+ if (!button->textutil)
+ gail_button_init_textutil (button, widget);
+ else
+ {
+ label_text = gtk_label_get_text (label);
+ gail_text_util_text_setup (button->textutil, label_text);
+ }
+ }
+
+ return 1;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ iface->do_action = gail_button_do_action;
+ iface->get_n_actions = gail_button_get_n_actions;
+ iface->get_description = gail_button_get_description;
+ iface->get_keybinding = gail_button_get_keybinding;
+ iface->get_name = gail_button_action_get_name;
+ iface->set_description = gail_button_set_description;
+}
+
+static gboolean
+gail_button_do_action (AtkAction *action,
+ gint i)
+{
+ GtkWidget *widget;
+ GailButton *button;
+ gboolean return_value = TRUE;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ button = GAIL_BUTTON (action);
+
+ switch (i)
+ {
+ case 0:
+ case 1:
+ case 2:
+ if (!button->action_queue)
+ {
+ button->action_queue = g_queue_new ();
+ }
+ g_queue_push_head (button->action_queue, GINT_TO_POINTER(i));
+ if (!button->action_idle_handler)
+ button->action_idle_handler = gdk_threads_add_idle (idle_do_action, button);
+ break;
+ default:
+ return_value = FALSE;
+ break;
+ }
+ return return_value;
+}
+
+static gboolean
+idle_do_action (gpointer data)
+{
+ GtkButton *button;
+ GtkWidget *widget;
+ GailButton *gail_button;
+ GdkEvent tmp_event;
+ GdkWindow *window;
+
+ gail_button = GAIL_BUTTON (data);
+ gail_button->action_idle_handler = 0;
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gail_button));
+ window = gtk_widget_get_window (widget);
+
+ tmp_event.button.type = GDK_BUTTON_RELEASE;
+ tmp_event.button.window = window;
+ tmp_event.button.button = 1;
+ tmp_event.button.send_event = TRUE;
+ tmp_event.button.time = GDK_CURRENT_TIME;
+ tmp_event.button.axes = NULL;
+
+ g_object_ref (gail_button);
+
+ if (widget == NULL /* State is defunct */ ||
+ !gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
+ {
+ g_object_unref (gail_button);
+ return FALSE;
+ }
+ else
+ gtk_widget_event (widget, &tmp_event);
+
+ button = GTK_BUTTON (widget);
+ while (!g_queue_is_empty (gail_button->action_queue))
+ {
+ gint action_number = GPOINTER_TO_INT(g_queue_pop_head (gail_button->action_queue));
+ if (gail_button->default_is_press)
+ {
+ if (action_number == 0)
+ action_number = 1;
+ else if (action_number == 1)
+ action_number = 0;
+ }
+ switch (action_number)
+ {
+ case 0:
+ /* first a press */
+
+ /* FIXME: Do not access public member
+ button->in_button = TRUE;
+ */
+ g_signal_emit_by_name (button, "enter");
+ /*
+ * Simulate a button press event. calling gtk_button_pressed() does
+ * not get the job done for a GtkOptionMenu.
+ */
+ tmp_event.button.type = GDK_BUTTON_PRESS;
+ tmp_event.button.window = window;
+ tmp_event.button.button = 1;
+ tmp_event.button.send_event = TRUE;
+ tmp_event.button.time = GDK_CURRENT_TIME;
+ tmp_event.button.axes = NULL;
+
+ gtk_widget_event (widget, &tmp_event);
+
+ /* then a release */
+ tmp_event.button.type = GDK_BUTTON_RELEASE;
+ gtk_widget_event (widget, &tmp_event);
+ /* FIXME: Do not access public member
+ button->in_button = FALSE;
+ */
+ g_signal_emit_by_name (button, "leave");
+ break;
+ case 1:
+ /* FIXME: Do not access public member
+ button->in_button = TRUE;
+ */
+ g_signal_emit_by_name (button, "enter");
+ /*
+ * Simulate a button press event. calling gtk_button_pressed() does
+ * not get the job done for a GtkOptionMenu.
+ */
+ tmp_event.button.type = GDK_BUTTON_PRESS;
+ tmp_event.button.window = window;
+ tmp_event.button.button = 1;
+ tmp_event.button.send_event = TRUE;
+ tmp_event.button.time = GDK_CURRENT_TIME;
+ tmp_event.button.axes = NULL;
+
+ gtk_widget_event (widget, &tmp_event);
+ break;
+ case 2:
+ /* FIXME: Do not access public member
+ button->in_button = FALSE;
+ */
+ g_signal_emit_by_name (button, "leave");
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+ g_object_unref (gail_button);
+ return FALSE;
+}
+
+static gint
+gail_button_get_n_actions (AtkAction *action)
+{
+ return 3;
+}
+
+static const gchar*
+gail_button_get_description (AtkAction *action,
+ gint i)
+{
+ GailButton *button;
+ const gchar *return_value;
+
+ button = GAIL_BUTTON (action);
+
+ if (button->default_is_press)
+ {
+ if (i == 0)
+ i = 1;
+ else if (i == 1)
+ i = 0;
+ }
+ switch (i)
+ {
+ case 0:
+ return_value = button->click_description;
+ break;
+ case 1:
+ return_value = button->press_description;
+ break;
+ case 2:
+ return_value = button->release_description;
+ break;
+ default:
+ return_value = NULL;
+ break;
+ }
+ return return_value;
+}
+
+static const gchar*
+gail_button_get_keybinding (AtkAction *action,
+ gint i)
+{
+ GailButton *button;
+ gchar *return_value = NULL;
+
+ button = GAIL_BUTTON (action);
+ if (button->default_is_press)
+ {
+ if (i == 0)
+ i = 1;
+ else if (i == 1)
+ i = 0;
+ }
+ switch (i)
+ {
+ case 0:
+ {
+ /*
+ * We look for a mnemonic on the label
+ */
+ GtkWidget *widget;
+ GtkWidget *label;
+ guint key_val;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (button));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ g_return_val_if_fail (GTK_IS_BUTTON (widget), NULL);
+
+ label = get_label_from_button (widget, 0, FALSE);
+ if (GTK_IS_LABEL (label))
+ {
+ key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
+ if (key_val != GDK_KEY_VoidSymbol)
+ return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
+ }
+ if (return_value == NULL)
+ {
+ /* Find labelled-by relation */
+ AtkRelationSet *set;
+ AtkRelation *relation;
+ GPtrArray *target;
+ gpointer target_object;
+
+ set = atk_object_ref_relation_set (ATK_OBJECT (action));
+ if (set)
+ {
+ relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
+ if (relation)
+ {
+ target = atk_relation_get_target (relation);
+
+ target_object = g_ptr_array_index (target, 0);
+ label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
+ }
+ g_object_unref (set);
+ }
+
+ if (GTK_IS_LABEL (label))
+ {
+ key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
+ if (key_val != GDK_KEY_VoidSymbol)
+ return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
+ }
+ }
+ g_free (button->click_keybinding);
+ button->click_keybinding = return_value;
+ break;
+ }
+ default:
+ break;
+ }
+ return return_value;
+}
+
+static const gchar*
+gail_button_action_get_name (AtkAction *action,
+ gint i)
+{
+ const gchar *return_value;
+ GailButton *button;
+
+ button = GAIL_BUTTON (action);
+
+ if (button->default_is_press)
+ {
+ if (i == 0)
+ i = 1;
+ else if (i == 1)
+ i = 0;
+ }
+ switch (i)
+ {
+ case 0:
+ /*
+ * This action is a "click" to activate a button or "toggle" to change
+ * the state of a toggle button check box or radio button.
+ */
+ return_value = "click";
+ break;
+ case 1:
+ /*
+ * This action simulates a button press by simulating moving the
+ * mouse into the button followed by pressing the left mouse button.
+ */
+ return_value = "press";
+ break;
+ case 2:
+ /*
+ * This action simulates releasing the left mouse button outside the
+ * button.
+ *
+ * To simulate releasing the left mouse button inside the button use
+ * the click action.
+ */
+ return_value = "release";
+ break;
+ default:
+ return_value = NULL;
+ break;
+ }
+ return return_value;
+}
+
+static gboolean
+gail_button_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc)
+{
+ GailButton *button;
+ gchar **value;
+
+ button = GAIL_BUTTON (action);
+
+ if (button->default_is_press)
+ {
+ if (i == 0)
+ i = 1;
+ else if (i == 1)
+ i = 0;
+ }
+ switch (i)
+ {
+ case 0:
+ value = &button->click_description;
+ break;
+ case 1:
+ value = &button->press_description;
+ break;
+ case 2:
+ value = &button->release_description;
+ break;
+ default:
+ value = NULL;
+ break;
+ }
+ if (value)
+ {
+ g_free (*value);
+ *value = g_strdup (desc);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gint
+gail_button_get_n_children (AtkObject* obj)
+{
+ GtkWidget *widget;
+ gint n_children;
+
+ g_return_val_if_fail (GAIL_IS_BUTTON (obj), 0);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return 0;
+
+ /*
+ * Check whether we have an attached menus for PanelMenuButton
+ */
+ n_children = get_n_attached_menus (widget);
+ if (n_children > 0)
+ return n_children;
+
+ n_children = get_n_labels_from_button (widget);
+ if (n_children <= 1)
+ n_children = 0;
+
+ return n_children;
+}
+
+static AtkObject*
+gail_button_ref_child (AtkObject *obj,
+ gint i)
+{
+ GtkWidget *widget;
+ GtkWidget *child_widget;
+ AtkObject *child;
+
+ g_return_val_if_fail (GAIL_IS_BUTTON (obj), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ if (i >= gail_button_get_n_children (obj))
+ return NULL;
+
+ if (get_n_attached_menus (widget) > 0)
+ {
+ child_widget = get_nth_attached_menu (widget, i);
+ }
+ else
+ child_widget = NULL;
+
+ if (!child_widget)
+ {
+ if (get_n_labels_from_button (widget) > 1)
+ {
+ child_widget = get_label_from_button (widget, i, TRUE);
+ }
+ }
+
+ if (child_widget)
+ {
+ child = gtk_widget_get_accessible (child_widget);
+ g_object_ref (child);
+ }
+ else
+ child = NULL;
+
+ return child;
+}
+
+static AtkStateSet*
+gail_button_ref_state_set (AtkObject *obj)
+{
+ AtkStateSet *state_set;
+ GtkWidget *widget;
+
+ state_set = ATK_OBJECT_CLASS (gail_button_parent_class)->ref_state_set (obj);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+
+ if (widget == NULL)
+ return state_set;
+
+ if (gtk_widget_get_state (widget) == GTK_STATE_ACTIVE)
+ atk_state_set_add_state (state_set, ATK_STATE_ARMED);
+
+ if (!gtk_widget_get_can_focus (widget))
+ atk_state_set_remove_state (state_set, ATK_STATE_SELECTABLE);
+
+
+ return state_set;
+}
+
+/*
+ * This is the signal handler for the "pressed" or "enter" signal handler
+ * on the GtkButton.
+ *
+ * If the state is now GTK_STATE_ACTIVE we notify a property change
+ */
+static void
+gail_button_pressed_enter_handler (GtkWidget *widget)
+{
+ AtkObject *accessible;
+
+ if (gtk_widget_get_state (widget) == GTK_STATE_ACTIVE)
+ {
+ accessible = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (accessible, ATK_STATE_ARMED, TRUE);
+ GAIL_BUTTON (accessible)->state = GTK_STATE_ACTIVE;
+ }
+}
+
+/*
+ * This is the signal handler for the "released" or "leave" signal handler
+ * on the GtkButton.
+ *
+ * If the state was GTK_STATE_ACTIVE we notify a property change
+ */
+static void
+gail_button_released_leave_handler (GtkWidget *widget)
+{
+ AtkObject *accessible;
+
+ accessible = gtk_widget_get_accessible (widget);
+ if (GAIL_BUTTON (accessible)->state == GTK_STATE_ACTIVE)
+ {
+ atk_object_notify_state_change (accessible, ATK_STATE_ARMED, FALSE);
+ GAIL_BUTTON (accessible)->state = GTK_STATE_NORMAL;
+ }
+}
+
+static void
+atk_image_interface_init (AtkImageIface *iface)
+{
+ iface->get_image_description = gail_button_get_image_description;
+ iface->get_image_position = gail_button_get_image_position;
+ iface->get_image_size = gail_button_get_image_size;
+ iface->set_image_description = gail_button_set_image_description;
+}
+
+static GtkImage*
+get_image_from_button (GtkWidget *button)
+{
+ GtkWidget *child;
+ GList *list;
+ GtkImage *image = NULL;
+
+ child = gtk_bin_get_child (GTK_BIN (button));
+ if (GTK_IS_IMAGE (child))
+ image = GTK_IMAGE (child);
+ else
+ {
+ if (GTK_IS_ALIGNMENT (child))
+ child = gtk_bin_get_child (GTK_BIN (child));
+ if (GTK_IS_CONTAINER (child))
+ {
+ list = gtk_container_get_children (GTK_CONTAINER (child));
+ if (!list)
+ return NULL;
+ if (GTK_IS_IMAGE (list->data))
+ image = GTK_IMAGE (list->data);
+ g_list_free (list);
+ }
+ }
+
+ return image;
+}
+
+static const gchar*
+gail_button_get_image_description (AtkImage *image) {
+
+ GtkWidget *widget;
+ GtkImage *button_image;
+ AtkObject *obj;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ button_image = get_image_from_button (widget);
+
+ if (button_image != NULL)
+ {
+ obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
+ return atk_image_get_image_description (ATK_IMAGE (obj));
+ }
+ else
+ return NULL;
+}
+
+static void
+gail_button_get_image_position (AtkImage *image,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type)
+{
+ GtkWidget *widget;
+ GtkImage *button_image;
+ AtkObject *obj;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
+
+ if (widget == NULL)
+ {
+ /*
+ * State is defunct
+ */
+ *x = G_MININT;
+ *y = G_MININT;
+ return;
+ }
+
+ button_image = get_image_from_button (widget);
+
+ if (button_image != NULL)
+ {
+ obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
+ atk_component_get_position (ATK_COMPONENT (obj), x, y, coord_type);
+ }
+ else
+ {
+ *x = G_MININT;
+ *y = G_MININT;
+ }
+}
+
+static void
+gail_button_get_image_size (AtkImage *image,
+ gint *width,
+ gint *height)
+{
+ GtkWidget *widget;
+ GtkImage *button_image;
+ AtkObject *obj;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
+
+ if (widget == NULL)
+ {
+ /*
+ * State is defunct
+ */
+ *width = -1;
+ *height = -1;
+ return;
+ }
+
+ button_image = get_image_from_button (widget);
+
+ if (button_image != NULL)
+ {
+ obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
+ atk_image_get_image_size (ATK_IMAGE (obj), width, height);
+ }
+ else
+ {
+ *width = -1;
+ *height = -1;
+ }
+}
+
+static gboolean
+gail_button_set_image_description (AtkImage *image,
+ const gchar *description)
+{
+ GtkWidget *widget;
+ GtkImage *button_image;
+ AtkObject *obj;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ button_image = get_image_from_button (widget);
+
+ if (button_image != NULL)
+ {
+ obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
+ return atk_image_set_image_description (ATK_IMAGE (obj), description);
+ }
+ else
+ return FALSE;
+}
+
+/* atktext.h */
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_button_get_text;
+ iface->get_character_at_offset = gail_button_get_character_at_offset;
+ iface->get_text_before_offset = gail_button_get_text_before_offset;
+ iface->get_text_at_offset = gail_button_get_text_at_offset;
+ iface->get_text_after_offset = gail_button_get_text_after_offset;
+ iface->get_character_count = gail_button_get_character_count;
+ iface->get_character_extents = gail_button_get_character_extents;
+ iface->get_offset_at_point = gail_button_get_offset_at_point;
+ iface->get_run_attributes = gail_button_get_run_attributes;
+ iface->get_default_attributes = gail_button_get_default_attributes;
+}
+
+static gchar*
+gail_button_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailButton *button;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL (label))
+ return NULL;
+
+ button = GAIL_BUTTON (text);
+ if (!button->textutil)
+ gail_button_init_textutil (button, label);
+
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+
+ if (label_text == NULL)
+ return NULL;
+ else
+ {
+ return gail_text_util_get_substring (button->textutil,
+ start_pos, end_pos);
+ }
+}
+
+static gchar*
+gail_button_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailButton *button;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get label */
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ button = GAIL_BUTTON (text);
+ if (!button->textutil)
+ gail_button_init_textutil (button, label);
+
+ return gail_text_util_get_text (button->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)), GAIL_BEFORE_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_button_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailButton *button;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get label */
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ button = GAIL_BUTTON (text);
+ if (!button->textutil)
+ gail_button_init_textutil (button, label);
+
+ return gail_text_util_get_text (button->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)), GAIL_AT_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_button_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailButton *button;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return NULL;
+ }
+
+ /* Get label */
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ button = GAIL_BUTTON (text);
+ if (!button->textutil)
+ gail_button_init_textutil (button, label);
+
+ return gail_text_util_get_text (button->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gint
+gail_button_get_character_count (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL(label))
+ return 0;
+
+ return g_utf8_strlen (gtk_label_get_text (GTK_LABEL (label)), -1);
+}
+
+static void
+gail_button_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ PangoRectangle char_rect;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL(label))
+ return;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
+ pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
+
+ gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
+ x_layout, y_layout, x, y, width, height, coords);
+}
+
+static gint
+gail_button_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL(label))
+ return -1;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+
+ index = gail_misc_get_index_at_point_in_layout (label,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ x_layout, y_layout, x, y, coords);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ if (index == -1)
+ {
+ if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
+ return g_utf8_strlen (label_text, -1);
+
+ return index;
+ }
+ else
+ return g_utf8_pointer_to_offset (label_text, label_text + index);
+}
+
+static AtkAttributeSet*
+gail_button_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkAttributeSet *at_set = NULL;
+ GtkJustification justify;
+ GtkTextDirection dir;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ /* Get values set for entire label, if any */
+ justify = gtk_label_get_justify (GTK_LABEL (label));
+ if (justify != GTK_JUSTIFY_CENTER)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_JUSTIFICATION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
+ }
+ dir = gtk_widget_get_direction (label);
+ if (dir == GTK_TEXT_DIR_RTL)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_DIRECTION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
+ }
+
+ at_set = gail_misc_layout_get_run_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ (gchar *) gtk_label_get_text (GTK_LABEL (label)),
+ offset,
+ start_offset,
+ end_offset);
+ return at_set;
+}
+
+static AtkAttributeSet*
+gail_button_get_default_attributes (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkAttributeSet *at_set = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ at_set = gail_misc_get_default_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ widget);
+ return at_set;
+}
+
+static gunichar
+gail_button_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ const gchar *string;
+ gchar *index;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return '\0';
+
+ label = get_label_from_button (widget, 0, FALSE);
+
+ if (!GTK_IS_LABEL(label))
+ return '\0';
+ string = gtk_label_get_text (GTK_LABEL (label));
+ if (offset >= g_utf8_strlen (string, -1))
+ return '\0';
+ index = g_utf8_offset_to_pointer (string, offset);
+
+ return g_utf8_get_char (index);
+}
+
+static void
+gail_button_finalize (GObject *object)
+{
+ GailButton *button = GAIL_BUTTON (object);
+
+ g_free (button->click_description);
+ g_free (button->press_description);
+ g_free (button->release_description);
+ g_free (button->click_keybinding);
+ if (button->action_idle_handler)
+ {
+ g_source_remove (button->action_idle_handler);
+ button->action_idle_handler = 0;
+ }
+ if (button->action_queue)
+ {
+ g_queue_free (button->action_queue);
+ }
+ if (button->textutil)
+ {
+ g_object_unref (button->textutil);
+ }
+ G_OBJECT_CLASS (gail_button_parent_class)->finalize (object);
+}
+
+static GtkWidget*
+find_label_child (GtkContainer *container,
+ gint *index,
+ gboolean allow_many)
+{
+ GList *children, *tmp_list;
+ GtkWidget *child;
+
+ children = gtk_container_get_children (container);
+
+ child = NULL;
+ for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
+ {
+ if (GTK_IS_LABEL (tmp_list->data))
+ {
+ if (!allow_many)
+ {
+ if (child)
+ {
+ child = NULL;
+ break;
+ }
+ child = GTK_WIDGET (tmp_list->data);
+ }
+ else
+ {
+ if (*index == 0)
+ {
+ child = GTK_WIDGET (tmp_list->data);
+ break;
+ }
+ (*index)--;
+ }
+ }
+ /*
+ * Label for button which are GtkTreeView column headers are in a
+ * GtkHBox in a GtkAlignment.
+ */
+ else if (GTK_IS_ALIGNMENT (tmp_list->data))
+ {
+ GtkWidget *widget;
+
+ widget = gtk_bin_get_child (GTK_BIN (tmp_list->data));
+ if (GTK_IS_LABEL (widget))
+ {
+ if (!allow_many)
+ {
+ if (child)
+ {
+ child = NULL;
+ break;
+ }
+ child = widget;
+ }
+ else
+ {
+ if (*index == 0)
+ {
+ child = widget;
+ break;
+ }
+ (*index)--;
+ }
+ }
+ }
+ else if (GTK_IS_CONTAINER (tmp_list->data))
+ {
+ child = find_label_child (GTK_CONTAINER (tmp_list->data), index, allow_many);
+ if (child)
+ break;
+ }
+ }
+ g_list_free (children);
+ return child;
+}
+
+static GtkWidget*
+get_label_from_button (GtkWidget *button,
+ gint index,
+ gboolean allow_many)
+{
+ GtkWidget *child;
+
+ if (index > 0 && !allow_many)
+ g_warning ("Inconsistent values passed to get_label_from_button");
+
+ child = gtk_bin_get_child (GTK_BIN (button));
+ if (GTK_IS_ALIGNMENT (child))
+ child = gtk_bin_get_child (GTK_BIN (child));
+
+ if (GTK_IS_CONTAINER (child))
+ child = find_label_child (GTK_CONTAINER (child), &index, allow_many);
+ else if (!GTK_IS_LABEL (child))
+ child = NULL;
+
+ return child;
+}
+
+static void
+count_labels (GtkContainer *container,
+ gint *n_labels)
+{
+ GList *children, *tmp_list;
+
+ children = gtk_container_get_children (container);
+
+ for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
+ {
+ if (GTK_IS_LABEL (tmp_list->data))
+ {
+ (*n_labels)++;
+ }
+ /*
+ * Label for button which are GtkTreeView column headers are in a
+ * GtkHBox in a GtkAlignment.
+ */
+ else if (GTK_IS_ALIGNMENT (tmp_list->data))
+ {
+ GtkWidget *widget;
+
+ widget = gtk_bin_get_child (GTK_BIN (tmp_list->data));
+ if (GTK_IS_LABEL (widget))
+ (*n_labels)++;
+ }
+ else if (GTK_IS_CONTAINER (tmp_list->data))
+ {
+ count_labels (GTK_CONTAINER (tmp_list->data), n_labels);
+ }
+ }
+ g_list_free (children);
+}
+
+static gint
+get_n_labels_from_button (GtkWidget *button)
+{
+ GtkWidget *child;
+ gint n_labels;
+
+ n_labels = 0;
+
+ child = gtk_bin_get_child (GTK_BIN (button));
+ if (GTK_IS_ALIGNMENT (child))
+ child = gtk_bin_get_child (GTK_BIN (child));
+
+ if (GTK_IS_CONTAINER (child))
+ count_labels (GTK_CONTAINER (child), &n_labels);
+
+ return n_labels;
+}
+
+static void
+set_role_for_button (AtkObject *accessible,
+ GtkWidget *button)
+{
+ GtkWidget *parent;
+ AtkRole role;
+
+ parent = gtk_widget_get_parent (button);
+ if (GTK_IS_TREE_VIEW (parent))
+ {
+ role = ATK_ROLE_TABLE_COLUMN_HEADER;
+ /*
+ * Even though the accessible parent of the column header will
+ * be reported as the table because the parent widget of the
+ * GtkTreeViewColumn's button is the GtkTreeView we set
+ * the accessible parent for column header to be the table
+ * to ensure that atk_object_get_index_in_parent() returns
+ * the correct value; see gail_widget_get_index_in_parent().
+ */
+ atk_object_set_parent (accessible, gtk_widget_get_accessible (parent));
+ }
+ else
+ role = ATK_ROLE_PUSH_BUTTON;
+
+ accessible->role = role;
+}
+
+static gint
+get_n_attached_menus (GtkWidget *widget)
+{
+ GList *list_menus;
+
+ if (widget == NULL)
+ return 0;
+
+ list_menus = g_object_get_data (G_OBJECT (widget), GAIL_BUTTON_ATTACHED_MENUS);
+ if (list_menus == NULL)
+ return 0;
+
+ return g_list_length (list_menus);
+}
+
+static GtkWidget*
+get_nth_attached_menu (GtkWidget *widget,
+ gint index)
+{
+ GtkWidget *attached_menu;
+ GList *list_menus;
+
+ if (widget == NULL)
+ return NULL;
+
+ list_menus = g_object_get_data (G_OBJECT (widget), GAIL_BUTTON_ATTACHED_MENUS);
+ if (list_menus == NULL ||
+ index >= g_list_length (list_menus))
+ return NULL;
+
+ attached_menu = (GtkWidget *) g_list_nth_data (list_menus, index);
+
+ return attached_menu;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_BUTTON_H__
+#define __GAIL_BUTTON_H__
+
+#include "gailcontainer.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_BUTTON (gail_button_get_type ())
+#define GAIL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_BUTTON, GailButton))
+#define GAIL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_BUTTON, GailButtonClass))
+#define GAIL_IS_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_BUTTON))
+#define GAIL_IS_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_BUTTON))
+#define GAIL_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_BUTTON, GailButtonClass))
+
+typedef struct _GailButton GailButton;
+typedef struct _GailButtonClass GailButtonClass;
+
+struct _GailButton
+{
+ GailContainer parent;
+
+ /*
+ * Cache the widget state so we know the previous state when it changed
+ */
+ gint8 state;
+
+ gchar *click_description;
+ gchar *press_description;
+ gchar *release_description;
+ gchar *click_keybinding;
+ guint action_idle_handler;
+ GQueue *action_queue;
+
+ GailTextUtil *textutil;
+
+ gboolean default_is_press;
+};
+
+GType gail_button_get_type (void);
+
+struct _GailButtonClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_BUTTON_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailcalendar.h"
+
+static void gail_calendar_class_init (GailCalendarClass *klass);
+static void gail_calendar_init (GailCalendar *calendar);
+static void gail_calendar_initialize (AtkObject *accessible,
+ gpointer data);
+
+G_DEFINE_TYPE (GailCalendar, gail_calendar, GAIL_TYPE_WIDGET)
+
+static void
+gail_calendar_class_init (GailCalendarClass *klass)
+{
+ AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
+
+ atk_object_class->initialize = gail_calendar_initialize;
+}
+
+static void
+gail_calendar_init (GailCalendar *calendar)
+{
+}
+
+static void
+gail_calendar_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_calendar_parent_class)->initialize (accessible, data);
+
+ accessible->role = ATK_ROLE_CALENDAR;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_CALENDAR_H__
+#define __GAIL_CALENDAR_H__
+
+#include "gailcontainer.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_CALENDAR (gail_calendar_get_type ())
+#define GAIL_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CALENDAR, GailCalendar))
+#define GAIL_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CALENDAR, GailCalendarClass))
+#define GAIL_IS_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CALENDAR))
+#define GAIL_IS_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CALENDAR))
+#define GAIL_CALENDAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CALENDAR, GailCalendarClass))
+
+typedef struct _GailCalendar GailCalendar;
+typedef struct _GailCalendarClass GailCalendarClass;
+
+struct _GailCalendar
+{
+ GailWidget parent;
+};
+
+GType gail_calendar_get_type (void);
+
+struct _GailCalendarClass
+{
+ GailWidgetClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_CALENDAR_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include "gailcontainercell.h"
+#include "gailcell.h"
+#include "gailcellparent.h"
+
+static void gail_cell_class_init (GailCellClass *klass);
+static void gail_cell_destroyed (GtkWidget *widget,
+ GailCell *cell);
+
+static void gail_cell_init (GailCell *cell);
+static void gail_cell_object_finalize (GObject *cell);
+static AtkStateSet* gail_cell_ref_state_set (AtkObject *obj);
+static gint gail_cell_get_index_in_parent (AtkObject *obj);
+
+/* AtkAction */
+
+static void atk_action_interface_init
+ (AtkActionIface *iface);
+static ActionInfo * _gail_cell_get_action_info (GailCell *cell,
+ gint index);
+static void _gail_cell_destroy_action_info
+ (gpointer data,
+ gpointer user_data);
+
+static gint gail_cell_action_get_n_actions
+ (AtkAction *action);
+static const gchar*
+ gail_cell_action_get_name (AtkAction *action,
+ gint index);
+static const gchar *
+ gail_cell_action_get_description
+ (AtkAction *action,
+ gint index);
+static gboolean gail_cell_action_set_description
+ (AtkAction *action,
+ gint index,
+ const gchar *desc);
+static const gchar *
+ gail_cell_action_get_keybinding
+ (AtkAction *action,
+ gint index);
+static gboolean gail_cell_action_do_action (AtkAction *action,
+ gint index);
+static gboolean idle_do_action (gpointer data);
+
+static void atk_component_interface_init (AtkComponentIface *iface);
+static void gail_cell_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+static gboolean gail_cell_grab_focus (AtkComponent *component);
+
+G_DEFINE_TYPE_WITH_CODE (GailCell, gail_cell, ATK_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
+
+static void
+gail_cell_class_init (GailCellClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+
+ g_object_class->finalize = gail_cell_object_finalize;
+
+ class->get_index_in_parent = gail_cell_get_index_in_parent;
+ class->ref_state_set = gail_cell_ref_state_set;
+}
+
+void
+gail_cell_initialise (GailCell *cell,
+ GtkWidget *widget,
+ AtkObject *parent,
+ gint index)
+{
+ g_return_if_fail (GAIL_IS_CELL (cell));
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ cell->widget = widget;
+ atk_object_set_parent (ATK_OBJECT (cell), parent);
+ cell->index = index;
+
+ g_signal_connect_object (G_OBJECT (widget),
+ "destroy",
+ G_CALLBACK (gail_cell_destroyed ),
+ cell, 0);
+}
+
+static void
+gail_cell_destroyed (GtkWidget *widget,
+ GailCell *cell)
+{
+ /*
+ * This is the signal handler for the "destroy" signal for the
+ * GtkWidget. We set the pointer location to NULL;
+ */
+ cell->widget = NULL;
+}
+
+static void
+gail_cell_init (GailCell *cell)
+{
+ cell->state_set = atk_state_set_new ();
+ cell->widget = NULL;
+ cell->action_list = NULL;
+ cell->index = 0;
+ atk_state_set_add_state (cell->state_set, ATK_STATE_TRANSIENT);
+ atk_state_set_add_state (cell->state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (cell->state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (cell->state_set, ATK_STATE_SELECTABLE);
+ cell->refresh_index = NULL;
+}
+
+static void
+gail_cell_object_finalize (GObject *obj)
+{
+ GailCell *cell = GAIL_CELL (obj);
+ AtkRelationSet *relation_set;
+ AtkRelation *relation;
+ GPtrArray *target;
+ gpointer target_object;
+ gint i;
+
+ if (cell->state_set)
+ g_object_unref (cell->state_set);
+ if (cell->action_list)
+ {
+ g_list_foreach (cell->action_list, _gail_cell_destroy_action_info, NULL);
+ g_list_free (cell->action_list);
+ }
+ if (cell->action_idle_handler)
+ {
+ g_source_remove (cell->action_idle_handler);
+ cell->action_idle_handler = 0;
+ }
+ relation_set = atk_object_ref_relation_set (ATK_OBJECT (obj));
+ if (ATK_IS_RELATION_SET (relation_set))
+ {
+ relation = atk_relation_set_get_relation_by_type (relation_set,
+ ATK_RELATION_NODE_CHILD_OF);
+ if (relation)
+ {
+ target = atk_relation_get_target (relation);
+ for (i = 0; i < target->len; i++)
+ {
+ target_object = g_ptr_array_index (target, i);
+ if (GAIL_IS_CELL (target_object))
+ {
+ g_object_unref (target_object);
+ }
+ }
+ }
+ g_object_unref (relation_set);
+ }
+ G_OBJECT_CLASS (gail_cell_parent_class)->finalize (obj);
+}
+
+static AtkStateSet *
+gail_cell_ref_state_set (AtkObject *obj)
+{
+ GailCell *cell = GAIL_CELL (obj);
+ g_assert (cell->state_set);
+
+ g_object_ref(cell->state_set);
+ return cell->state_set;
+}
+
+gboolean
+gail_cell_add_state (GailCell *cell,
+ AtkStateType state_type,
+ gboolean emit_signal)
+{
+ if (!atk_state_set_contains_state (cell->state_set, state_type))
+ {
+ gboolean rc;
+ AtkObject *parent;
+
+ rc = atk_state_set_add_state (cell->state_set, state_type);
+ /*
+ * The signal should only be generated if the value changed,
+ * not when the cell is set up. So states that are set
+ * initially should pass FALSE as the emit_signal argument.
+ */
+
+ if (emit_signal)
+ {
+ atk_object_notify_state_change (ATK_OBJECT (cell), state_type, TRUE);
+ /* If state_type is ATK_STATE_VISIBLE, additional notification */
+ if (state_type == ATK_STATE_VISIBLE)
+ g_signal_emit_by_name (cell, "visible_data_changed");
+ }
+
+ /*
+ * If the parent is a flyweight container cell, propagate the state
+ * change to it also
+ */
+
+ parent = atk_object_get_parent (ATK_OBJECT (cell));
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ gail_cell_add_state (GAIL_CELL (parent), state_type, emit_signal);
+ return rc;
+ }
+ else
+ return FALSE;
+}
+
+gboolean
+gail_cell_remove_state (GailCell *cell,
+ AtkStateType state_type,
+ gboolean emit_signal)
+{
+ if (atk_state_set_contains_state (cell->state_set, state_type))
+ {
+ gboolean rc;
+ AtkObject *parent;
+
+ parent = atk_object_get_parent (ATK_OBJECT (cell));
+
+ rc = atk_state_set_remove_state (cell->state_set, state_type);
+ /*
+ * The signal should only be generated if the value changed,
+ * not when the cell is set up. So states that are set
+ * initially should pass FALSE as the emit_signal argument.
+ */
+
+ if (emit_signal)
+ {
+ atk_object_notify_state_change (ATK_OBJECT (cell), state_type, FALSE);
+ /* If state_type is ATK_STATE_VISIBLE, additional notification */
+ if (state_type == ATK_STATE_VISIBLE)
+ g_signal_emit_by_name (cell, "visible_data_changed");
+ }
+
+ /*
+ * If the parent is a flyweight container cell, propagate the state
+ * change to it also
+ */
+
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ gail_cell_remove_state (GAIL_CELL (parent), state_type, emit_signal);
+ return rc;
+ }
+ else
+ return FALSE;
+}
+
+static gint
+gail_cell_get_index_in_parent (AtkObject *obj)
+{
+ GailCell *cell;
+
+ g_assert (GAIL_IS_CELL (obj));
+
+ cell = GAIL_CELL (obj);
+ if (atk_state_set_contains_state (cell->state_set, ATK_STATE_STALE))
+ if (cell->refresh_index)
+ {
+ cell->refresh_index (cell);
+ atk_state_set_remove_state (cell->state_set, ATK_STATE_STALE);
+ }
+ return cell->index;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ iface->get_n_actions = gail_cell_action_get_n_actions;
+ iface->do_action = gail_cell_action_do_action;
+ iface->get_name = gail_cell_action_get_name;
+ iface->get_description = gail_cell_action_get_description;
+ iface->set_description = gail_cell_action_set_description;
+ iface->get_keybinding = gail_cell_action_get_keybinding;
+}
+
+gboolean
+gail_cell_add_action (GailCell *cell,
+ const gchar *action_name,
+ const gchar *action_description,
+ const gchar *action_keybinding,
+ ACTION_FUNC action_func)
+{
+ ActionInfo *info;
+ g_return_val_if_fail (GAIL_IS_CELL (cell), FALSE);
+ info = g_new (ActionInfo, 1);
+
+ if (action_name != NULL)
+ info->name = g_strdup (action_name);
+ else
+ info->name = NULL;
+ if (action_description != NULL)
+ info->description = g_strdup (action_description);
+ else
+ info->description = NULL;
+ if (action_keybinding != NULL)
+ info->keybinding = g_strdup (action_keybinding);
+ else
+ info->keybinding = NULL;
+ info->do_action_func = action_func;
+
+ cell->action_list = g_list_append (cell->action_list, (gpointer) info);
+ return TRUE;
+}
+
+gboolean
+gail_cell_remove_action (GailCell *cell,
+ gint action_index)
+{
+ GList *list_node;
+
+ g_return_val_if_fail (GAIL_IS_CELL (cell), FALSE);
+ list_node = g_list_nth (cell->action_list, action_index);
+ if (!list_node)
+ return FALSE;
+ _gail_cell_destroy_action_info (list_node->data, NULL);
+ cell->action_list = g_list_remove_link (cell->action_list, list_node);
+ return TRUE;
+}
+
+
+gboolean
+gail_cell_remove_action_by_name (GailCell *cell,
+ const gchar *action_name)
+{
+ GList *list_node;
+ gboolean action_found= FALSE;
+
+ g_return_val_if_fail (GAIL_IS_CELL (cell), FALSE);
+ for (list_node = cell->action_list; list_node && !action_found;
+ list_node = list_node->next)
+ {
+ if (!strcmp (((ActionInfo *)(list_node->data))->name, action_name))
+ {
+ action_found = TRUE;
+ break;
+ }
+ }
+ if (!action_found)
+ return FALSE;
+ _gail_cell_destroy_action_info (list_node->data, NULL);
+ cell->action_list = g_list_remove_link (cell->action_list, list_node);
+ return TRUE;
+}
+
+static ActionInfo *
+_gail_cell_get_action_info (GailCell *cell,
+ gint index)
+{
+ GList *list_node;
+
+ g_return_val_if_fail (GAIL_IS_CELL (cell), NULL);
+ if (cell->action_list == NULL)
+ return NULL;
+ list_node = g_list_nth (cell->action_list, index);
+ if (!list_node)
+ return NULL;
+ return (ActionInfo *) (list_node->data);
+}
+
+
+static void
+_gail_cell_destroy_action_info (gpointer action_info,
+ gpointer user_data)
+{
+ ActionInfo *info = (ActionInfo *)action_info;
+ g_assert (info != NULL);
+ g_free (info->name);
+ g_free (info->description);
+ g_free (info->keybinding);
+ g_free (info);
+}
+static gint
+gail_cell_action_get_n_actions (AtkAction *action)
+{
+ GailCell *cell = GAIL_CELL(action);
+ if (cell->action_list != NULL)
+ return g_list_length (cell->action_list);
+ else
+ return 0;
+}
+
+static const gchar *
+gail_cell_action_get_name (AtkAction *action,
+ gint index)
+{
+ GailCell *cell = GAIL_CELL(action);
+ ActionInfo *info = _gail_cell_get_action_info (cell, index);
+
+ if (info == NULL)
+ return NULL;
+ return info->name;
+}
+
+static const gchar *
+gail_cell_action_get_description (AtkAction *action,
+ gint index)
+{
+ GailCell *cell = GAIL_CELL(action);
+ ActionInfo *info = _gail_cell_get_action_info (cell, index);
+
+ if (info == NULL)
+ return NULL;
+ return info->description;
+}
+
+static gboolean
+gail_cell_action_set_description (AtkAction *action,
+ gint index,
+ const gchar *desc)
+{
+ GailCell *cell = GAIL_CELL(action);
+ ActionInfo *info = _gail_cell_get_action_info (cell, index);
+
+ if (info == NULL)
+ return FALSE;
+ g_free (info->description);
+ info->description = g_strdup (desc);
+ return TRUE;
+}
+
+static const gchar *
+gail_cell_action_get_keybinding (AtkAction *action,
+ gint index)
+{
+ GailCell *cell = GAIL_CELL(action);
+ ActionInfo *info = _gail_cell_get_action_info (cell, index);
+ if (info == NULL)
+ return NULL;
+ return info->keybinding;
+}
+
+static gboolean
+gail_cell_action_do_action (AtkAction *action,
+ gint index)
+{
+ GailCell *cell = GAIL_CELL(action);
+ ActionInfo *info = _gail_cell_get_action_info (cell, index);
+ if (info == NULL)
+ return FALSE;
+ if (info->do_action_func == NULL)
+ return FALSE;
+ if (cell->action_idle_handler)
+ return FALSE;
+ cell->action_func = info->do_action_func;
+ cell->action_idle_handler = gdk_threads_add_idle (idle_do_action, cell);
+ return TRUE;
+}
+
+static gboolean
+idle_do_action (gpointer data)
+{
+ GailCell *cell;
+
+ cell = GAIL_CELL (data);
+ cell->action_idle_handler = 0;
+ cell->action_func (cell);
+
+ return FALSE;
+}
+
+static void
+atk_component_interface_init (AtkComponentIface *iface)
+{
+ iface->get_extents = gail_cell_get_extents;
+ iface->grab_focus = gail_cell_grab_focus;
+}
+
+static void
+gail_cell_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ GailCell *gailcell;
+ AtkObject *cell_parent;
+
+ g_assert (GAIL_IS_CELL (component));
+
+ gailcell = GAIL_CELL (component);
+
+ cell_parent = gtk_widget_get_accessible (gailcell->widget);
+
+ gail_cell_parent_get_cell_extents (GAIL_CELL_PARENT (cell_parent),
+ gailcell, x, y, width, height, coord_type);
+}
+
+static gboolean
+gail_cell_grab_focus (AtkComponent *component)
+{
+ GailCell *gailcell;
+ AtkObject *cell_parent;
+
+ g_assert (GAIL_IS_CELL (component));
+
+ gailcell = GAIL_CELL (component);
+
+ cell_parent = gtk_widget_get_accessible (gailcell->widget);
+
+ return gail_cell_parent_grab_focus (GAIL_CELL_PARENT (cell_parent),
+ gailcell);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_CELL_H__
+#define __GAIL_CELL_H__
+
+#include <atk/atk.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_CELL (gail_cell_get_type ())
+#define GAIL_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CELL, GailCell))
+#define GAIL_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CELL, GailCellClass))
+#define GAIL_IS_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CELL))
+#define GAIL_IS_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CELL))
+#define GAIL_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CELL, GailCellClass))
+
+typedef struct _GailCell GailCell;
+typedef struct _GailCellClass GailCellClass;
+typedef struct _ActionInfo ActionInfo;
+typedef void (*ACTION_FUNC) (GailCell *cell);
+
+struct _GailCell
+{
+ AtkObject parent;
+
+ GtkWidget *widget;
+ /*
+ * This cached value is used only by atk_object_get_index_in_parent()
+ * which updates the value when it is stale.
+ */
+ gint index;
+ AtkStateSet *state_set;
+ GList *action_list;
+ void (*refresh_index) (GailCell *cell);
+ gint action_idle_handler;
+ ACTION_FUNC action_func;
+};
+
+GType gail_cell_get_type (void);
+
+struct _GailCellClass
+{
+ AtkObjectClass parent_class;
+};
+
+struct _ActionInfo {
+ gchar *name;
+ gchar *description;
+ gchar *keybinding;
+ ACTION_FUNC do_action_func;
+};
+
+void gail_cell_initialise (GailCell *cell,
+ GtkWidget *widget,
+ AtkObject *parent,
+ gint index);
+
+gboolean gail_cell_add_state (GailCell *cell,
+ AtkStateType state_type,
+ gboolean emit_signal);
+
+gboolean gail_cell_remove_state (GailCell *cell,
+ AtkStateType state_type,
+ gboolean emit_signal);
+
+gboolean gail_cell_add_action (GailCell *cell,
+ const gchar *action_name,
+ const gchar *action_description,
+ const gchar *action_keybinding,
+ ACTION_FUNC action_func);
+
+gboolean gail_cell_remove_action (GailCell *cell,
+ gint action_id);
+
+gboolean gail_cell_remove_action_by_name (GailCell *cell,
+ const gchar *action_name);
+
+G_END_DECLS
+
+#endif /* __GAIL_CELL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailcellparent.h"
+
+GType
+gail_cell_parent_get_type (void)
+{
+ static volatile gsize g_define_type_id__volatile = 0;
+
+ if (g_once_init_enter (&g_define_type_id__volatile))
+ {
+ GType g_define_type_id =
+ g_type_register_static_simple (G_TYPE_INTERFACE,
+ "GailCellParent",
+ sizeof (GailCellParentIface),
+ NULL,
+ 0,
+ NULL,
+ 0);
+
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+ }
+
+ return g_define_type_id__volatile;
+}
+
+/**
+ * gail_cell_parent_get_cell_extents:
+ * @parent: a #GObject instance that implements GailCellParentIface
+ * @cell: a #GailCell whose extents is required
+ * @x: address of #gint to put x coordinate
+ * @y: address of #gint to put y coordinate
+ * @width: address of #gint to put width
+ * @height: address of #gint to put height
+ * @coord_type: specifies whether the coordinates are relative to the screen
+ * or to the components top level window
+ *
+ * Gets the rectangle which gives the extent of the @cell.
+ *
+ **/
+void
+gail_cell_parent_get_cell_extents (GailCellParent *parent,
+ GailCell *cell,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ GailCellParentIface *iface;
+
+ g_return_if_fail (GAIL_IS_CELL_PARENT (parent));
+
+ iface = GAIL_CELL_PARENT_GET_IFACE (parent);
+
+ if (iface->get_cell_extents)
+ (iface->get_cell_extents) (parent, cell, x, y, width, height, coord_type);
+}
+
+/**
+ * gail_cell_parent_get_cell_area:
+ * @parent: a #GObject instance that implements GailCellParentIface
+ * @cell: a #GailCell whose area is required
+ * @cell_rect: address of #GdkRectangle to put the cell area
+ *
+ * Gets the cell area of the @cell.
+ *
+ **/
+void
+gail_cell_parent_get_cell_area (GailCellParent *parent,
+ GailCell *cell,
+ GdkRectangle *cell_rect)
+{
+ GailCellParentIface *iface;
+
+ g_return_if_fail (GAIL_IS_CELL_PARENT (parent));
+ g_return_if_fail (cell_rect);
+
+ iface = GAIL_CELL_PARENT_GET_IFACE (parent);
+
+ if (iface->get_cell_area)
+ (iface->get_cell_area) (parent, cell, cell_rect);
+}
+/**
+ * gail_cell_parent_grab_focus:
+ * @parent: a #GObject instance that implements GailCellParentIface
+ * @cell: a #GailCell whose area is required
+ *
+ * Puts focus in the specified cell.
+ *
+ **/
+gboolean
+gail_cell_parent_grab_focus (GailCellParent *parent,
+ GailCell *cell)
+{
+ GailCellParentIface *iface;
+
+ g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), FALSE);
+
+ iface = GAIL_CELL_PARENT_GET_IFACE (parent);
+
+ if (iface->grab_focus)
+ return (iface->grab_focus) (parent, cell);
+ else
+ return FALSE;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ *
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_CELL_PARENT_H__
+#define __GAIL_CELL_PARENT_H__
+
+#include <atk/atk.h>
+#include "gailcell.h"
+
+G_BEGIN_DECLS
+
+/*
+ * The GailCellParent interface should be supported by any object which
+ * contains children which are flyweights, i.e. do not have corresponding
+ * widgets and the children need help from their parent to provide
+ * functionality. One example is GailTreeView where the children GailCell
+ * need help from the GailTreeView in order to implement
+ * atk_component_get_extents
+ */
+
+#define GAIL_TYPE_CELL_PARENT (gail_cell_parent_get_type ())
+#define GAIL_IS_CELL_PARENT(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CELL_PARENT)
+#define GAIL_CELL_PARENT(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CELL_PARENT, GailCellParent)
+#define GAIL_CELL_PARENT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GAIL_TYPE_CELL_PARENT, GailCellParentIface))
+
+#ifndef _TYPEDEF_GAIL_CELL_PARENT_
+#define _TYPEDEF_GAIL_CELL_PARENT_
+typedef struct _GailCellParent GailCellParent;
+#endif
+typedef struct _GailCellParentIface GailCellParentIface;
+
+struct _GailCellParentIface
+{
+ GTypeInterface parent;
+ void ( *get_cell_extents) (GailCellParent *parent,
+ GailCell *cell,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+ void ( *get_cell_area) (GailCellParent *parent,
+ GailCell *cell,
+ GdkRectangle *cell_rect);
+ gboolean ( *grab_focus) (GailCellParent *parent,
+ GailCell *cell);
+};
+
+GType gail_cell_parent_get_type (void);
+
+void gail_cell_parent_get_cell_extents (GailCellParent *parent,
+ GailCell *cell,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type
+);
+void gail_cell_parent_get_cell_area (GailCellParent *parent,
+ GailCell *cell,
+ GdkRectangle *cell_rect);
+gboolean gail_cell_parent_grab_focus (GailCellParent *parent,
+ GailCell *cell);
+
+G_END_DECLS
+
+#endif /* __GAIL_CELL_PARENT_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include "gailcheckmenuitem.h"
+#include "gailchecksubmenuitem.h"
+
+static void gail_check_menu_item_class_init (GailCheckMenuItemClass *klass);
+
+static void gail_check_menu_item_init (GailCheckMenuItem *item);
+
+static void gail_check_menu_item_toggled_gtk (GtkWidget *widget);
+
+static void gail_check_menu_item_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+
+static void gail_check_menu_item_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static AtkStateSet* gail_check_menu_item_ref_state_set (AtkObject *accessible);
+
+G_DEFINE_TYPE (GailCheckMenuItem, gail_check_menu_item, GAIL_TYPE_MENU_ITEM)
+
+static void
+gail_check_menu_item_class_init (GailCheckMenuItemClass *klass)
+{
+ GailWidgetClass *widget_class;
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ widget_class = (GailWidgetClass*)klass;
+ widget_class->notify_gtk = gail_check_menu_item_real_notify_gtk;
+
+ class->ref_state_set = gail_check_menu_item_ref_state_set;
+ class->initialize = gail_check_menu_item_real_initialize;
+}
+
+static void
+gail_check_menu_item_init (GailCheckMenuItem *item)
+{
+}
+
+AtkObject*
+gail_check_menu_item_new (GtkWidget *widget)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (widget), NULL);
+
+ if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)))
+ return gail_check_sub_menu_item_new (widget);
+
+ object = g_object_new (GAIL_TYPE_CHECK_MENU_ITEM, NULL);
+
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, widget);
+
+ return accessible;
+}
+
+static void
+gail_check_menu_item_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_check_menu_item_parent_class)->initialize (obj, data);
+
+ g_signal_connect (data,
+ "toggled",
+ G_CALLBACK (gail_check_menu_item_toggled_gtk),
+ NULL);
+
+ obj->role = ATK_ROLE_CHECK_MENU_ITEM;
+}
+
+static void
+gail_check_menu_item_toggled_gtk (GtkWidget *widget)
+{
+ AtkObject *accessible;
+ GtkCheckMenuItem *check_menu_item;
+
+ check_menu_item = GTK_CHECK_MENU_ITEM (widget);
+
+ accessible = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (accessible, ATK_STATE_CHECKED,
+ gtk_check_menu_item_get_active (check_menu_item));
+}
+
+static AtkStateSet*
+gail_check_menu_item_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GtkCheckMenuItem *check_menu_item;
+ GtkWidget *widget;
+
+ state_set = ATK_OBJECT_CLASS (gail_check_menu_item_parent_class)->ref_state_set (accessible);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ return state_set;
+
+ check_menu_item = GTK_CHECK_MENU_ITEM (widget);
+
+ if (gtk_check_menu_item_get_active (check_menu_item))
+ atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
+
+ if (gtk_check_menu_item_get_inconsistent (check_menu_item))
+ {
+ atk_state_set_remove_state (state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (state_set, ATK_STATE_INDETERMINATE);
+ }
+
+ return state_set;
+}
+
+static void
+gail_check_menu_item_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (obj);
+ AtkObject *atk_obj;
+ gboolean sensitive;
+ gboolean inconsistent;
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (check_menu_item));
+ sensitive = gtk_widget_get_sensitive (GTK_WIDGET (check_menu_item));
+ inconsistent = gtk_check_menu_item_get_inconsistent (check_menu_item);
+
+ if (strcmp (pspec->name, "inconsistent") == 0)
+ {
+ atk_object_notify_state_change (atk_obj, ATK_STATE_INDETERMINATE, inconsistent);
+ atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
+ }
+ else if (strcmp (pspec->name, "sensitive") == 0)
+ {
+ /* Need to override gailwidget behavior of notifying for ENABLED */
+ atk_object_notify_state_change (atk_obj, ATK_STATE_SENSITIVE, sensitive);
+ atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_check_menu_item_parent_class)->notify_gtk (obj, pspec);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_CHECK_MENU_ITEM_H__
+#define __GAIL_CHECK_MENU_ITEM_H__
+
+#include "gailmenuitem.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_CHECK_MENU_ITEM (gail_check_menu_item_get_type ())
+#define GAIL_CHECK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CHECK_MENU_ITEM, GailCheckMenuItem))
+#define GAIL_CHECK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CHECK_MENU_ITEM, GailCheckMenuItemClass))
+#define GAIL_IS_CHECK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CHECK_MENU_ITEM))
+#define GAIL_IS_CHECK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CHECK_MENU_ITEM))
+#define GAIL_CHECK_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CHECK_MENU_ITEM, GailCheckMenuItemClass))
+
+typedef struct _GailCheckMenuItem GailCheckMenuItem;
+typedef struct _GailCheckMenuItemClass GailCheckMenuItemClass;
+
+struct _GailCheckMenuItem
+{
+ GailMenuItem parent;
+};
+
+GType gail_check_menu_item_get_type (void);
+
+struct _GailCheckMenuItemClass
+{
+ GailMenuItemClass parent_class;
+};
+
+AtkObject* gail_check_menu_item_new (GtkWidget *widget);
+
+G_END_DECLS
+
+#endif /* __GAIL_CHECK_MENU_ITEM_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailchecksubmenuitem.h"
+
+static void gail_check_sub_menu_item_class_init (GailCheckSubMenuItemClass *klass);
+
+static void gail_check_sub_menu_item_init (GailCheckSubMenuItem *item);
+
+static void gail_check_sub_menu_item_toggled_gtk (GtkWidget *widget);
+
+static void gail_check_sub_menu_item_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+
+static void gail_check_sub_menu_item_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static AtkStateSet* gail_check_sub_menu_item_ref_state_set (AtkObject *accessible);
+
+G_DEFINE_TYPE (GailCheckSubMenuItem, gail_check_sub_menu_item, GAIL_TYPE_SUB_MENU_ITEM)
+
+static void
+gail_check_sub_menu_item_class_init (GailCheckSubMenuItemClass *klass)
+{
+ GailWidgetClass *widget_class;
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ widget_class = (GailWidgetClass*)klass;
+ widget_class->notify_gtk = gail_check_sub_menu_item_real_notify_gtk;
+
+ class->ref_state_set = gail_check_sub_menu_item_ref_state_set;
+ class->initialize = gail_check_sub_menu_item_real_initialize;
+}
+
+static void
+gail_check_sub_menu_item_init (GailCheckSubMenuItem *item)
+{
+}
+
+AtkObject*
+gail_check_sub_menu_item_new (GtkWidget *widget)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (widget), NULL);
+
+ object = g_object_new (GAIL_TYPE_CHECK_SUB_MENU_ITEM, NULL);
+
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, widget);
+
+ return accessible;
+}
+
+static void
+gail_check_sub_menu_item_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_check_sub_menu_item_parent_class)->initialize (obj, data);
+
+ g_signal_connect (data,
+ "toggled",
+ G_CALLBACK (gail_check_sub_menu_item_toggled_gtk),
+ NULL);
+
+ obj->role = ATK_ROLE_CHECK_MENU_ITEM;
+}
+
+static void
+gail_check_sub_menu_item_toggled_gtk (GtkWidget *widget)
+{
+ AtkObject *accessible;
+ GtkCheckMenuItem *check_menu_item;
+
+ check_menu_item = GTK_CHECK_MENU_ITEM (widget);
+
+ accessible = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (accessible, ATK_STATE_CHECKED,
+ gtk_check_menu_item_get_active (check_menu_item));
+}
+
+static AtkStateSet*
+gail_check_sub_menu_item_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GtkCheckMenuItem *check_menu_item;
+ GtkWidget *widget;
+
+ state_set = ATK_OBJECT_CLASS (gail_check_sub_menu_item_parent_class)->ref_state_set (accessible);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ return state_set;
+
+ check_menu_item = GTK_CHECK_MENU_ITEM (widget);
+
+ if (gtk_check_menu_item_get_active (check_menu_item))
+ atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
+
+ if (gtk_check_menu_item_get_inconsistent (check_menu_item))
+ {
+ atk_state_set_remove_state (state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (state_set, ATK_STATE_INDETERMINATE);
+ }
+
+ return state_set;
+}
+
+static void
+gail_check_sub_menu_item_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (obj);
+ AtkObject *atk_obj;
+ gboolean sensitive;
+ gboolean inconsistent;
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (check_menu_item));
+ sensitive = gtk_widget_get_sensitive (GTK_WIDGET (check_menu_item));
+ inconsistent = gtk_check_menu_item_get_inconsistent (check_menu_item);
+
+ if (strcmp (pspec->name, "inconsistent") == 0)
+ {
+ atk_object_notify_state_change (atk_obj, ATK_STATE_INDETERMINATE, inconsistent);
+ atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
+ }
+ else if (strcmp (pspec->name, "sensitive") == 0)
+ {
+ /* Need to override gailwidget behavior of notifying for ENABLED */
+ atk_object_notify_state_change (atk_obj, ATK_STATE_SENSITIVE, sensitive);
+ atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_check_sub_menu_item_parent_class)->notify_gtk (obj, pspec);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_CHECK_SUB_MENU_ITEM_H__
+#define __GAIL_CHECK_SUB_MENU_ITEM_H__
+
+#include "gailsubmenuitem.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_CHECK_SUB_MENU_ITEM (gail_check_sub_menu_item_get_type ())
+#define GAIL_CHECK_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CHECK_SUB_MENU_ITEM, GailCheckSubMenuItem))
+#define GAIL_CHECK_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CHECK_SUB_MENU_ITEM, GailCheckSubMenuItemClass))
+#define GAIL_IS_CHECK_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CHECK_SUB_MENU_ITEM))
+#define GAIL_IS_CHECK_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CHECK_SUB_MENU_ITEM))
+#define GAIL_CHECK_SUB_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CHECK_SUB_MENU_ITEM, GailCheckSubMenuItemClass))
+
+typedef struct _GailCheckSubMenuItem GailCheckSubMenuItem;
+typedef struct _GailCheckSubMenuItemClass GailCheckSubMenuItemClass;
+
+struct _GailCheckSubMenuItem
+{
+ GailSubMenuItem parent;
+};
+
+GType gail_check_sub_menu_item_get_type (void);
+
+struct _GailCheckSubMenuItemClass
+{
+ GailSubMenuItemClass parent_class;
+};
+
+AtkObject* gail_check_sub_menu_item_new (GtkWidget *widget);
+
+G_END_DECLS
+
+#endif /* __GAIL_CHECK_SUB_MENU_ITEM_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2004 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "gailcombobox.h"
+
+static void gail_combo_box_class_init (GailComboBoxClass *klass);
+static void gail_combo_box_init (GailComboBox *combo_box);
+static void gail_combo_box_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static void gail_combo_box_changed_gtk (GtkWidget *widget);
+
+static const gchar* gail_combo_box_get_name (AtkObject *obj);
+static gint gail_combo_box_get_n_children (AtkObject *obj);
+static AtkObject* gail_combo_box_ref_child (AtkObject *obj,
+ gint i);
+static void gail_combo_box_finalize (GObject *object);
+static void atk_action_interface_init (AtkActionIface *iface);
+
+static gboolean gail_combo_box_do_action (AtkAction *action,
+ gint i);
+static gboolean idle_do_action (gpointer data);
+static gint gail_combo_box_get_n_actions (AtkAction *action);
+static const gchar* gail_combo_box_get_description(AtkAction *action,
+ gint i);
+static const gchar* gail_combo_box_get_keybinding (AtkAction *action,
+ gint i);
+static const gchar* gail_combo_box_action_get_name(AtkAction *action,
+ gint i);
+static gboolean gail_combo_box_set_description(AtkAction *action,
+ gint i,
+ const gchar *desc);
+static void atk_selection_interface_init (AtkSelectionIface *iface);
+static gboolean gail_combo_box_add_selection (AtkSelection *selection,
+ gint i);
+static gboolean gail_combo_box_clear_selection (AtkSelection *selection);
+static AtkObject* gail_combo_box_ref_selection (AtkSelection *selection,
+ gint i);
+static gint gail_combo_box_get_selection_count (AtkSelection *selection);
+static gboolean gail_combo_box_is_child_selected (AtkSelection *selection,
+ gint i);
+static gboolean gail_combo_box_remove_selection (AtkSelection *selection,
+ gint i);
+
+G_DEFINE_TYPE_WITH_CODE (GailComboBox, gail_combo_box, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
+
+static void
+gail_combo_box_class_init (GailComboBoxClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = gail_combo_box_finalize;
+
+ class->get_name = gail_combo_box_get_name;
+ class->get_n_children = gail_combo_box_get_n_children;
+ class->ref_child = gail_combo_box_ref_child;
+ class->initialize = gail_combo_box_real_initialize;
+}
+
+static void
+gail_combo_box_init (GailComboBox *combo_box)
+{
+ combo_box->press_description = NULL;
+ combo_box->press_keybinding = NULL;
+ combo_box->old_selection = -1;
+ combo_box->name = NULL;
+ combo_box->popup_set = FALSE;
+}
+
+static void
+gail_combo_box_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkComboBox *combo_box;
+ GailComboBox *gail_combo_box;
+ AtkObject *popup;
+
+ ATK_OBJECT_CLASS (gail_combo_box_parent_class)->initialize (obj, data);
+
+ combo_box = GTK_COMBO_BOX (data);
+
+ gail_combo_box = GAIL_COMBO_BOX (obj);
+
+ g_signal_connect (combo_box,
+ "changed",
+ G_CALLBACK (gail_combo_box_changed_gtk),
+ NULL);
+ gail_combo_box->old_selection = gtk_combo_box_get_active (combo_box);
+
+ popup = gtk_combo_box_get_popup_accessible (combo_box);
+ if (popup)
+ {
+ atk_object_set_parent (popup, obj);
+ gail_combo_box->popup_set = TRUE;
+ }
+ if (gtk_combo_box_get_has_entry (combo_box))
+ atk_object_set_parent (gtk_widget_get_accessible (gtk_bin_get_child (GTK_BIN (combo_box))), obj);
+
+ obj->role = ATK_ROLE_COMBO_BOX;
+}
+
+static void
+gail_combo_box_changed_gtk (GtkWidget *widget)
+{
+ GtkComboBox *combo_box;
+ AtkObject *obj;
+ GailComboBox *gail_combo_box;
+ gint index;
+
+ combo_box = GTK_COMBO_BOX (widget);
+
+ index = gtk_combo_box_get_active (combo_box);
+ obj = gtk_widget_get_accessible (widget);
+ gail_combo_box = GAIL_COMBO_BOX (obj);
+ if (gail_combo_box->old_selection != index)
+ {
+ gail_combo_box->old_selection = index;
+ g_object_notify (G_OBJECT (obj), "accessible-name");
+ g_signal_emit_by_name (obj, "selection_changed");
+ }
+}
+
+static const gchar*
+gail_combo_box_get_name (AtkObject *obj)
+{
+ GtkWidget *widget;
+ GtkComboBox *combo_box;
+ GailComboBox *gail_combo_box;
+ GtkTreeIter iter;
+ const gchar *name;
+ GtkTreeModel *model;
+ gint n_columns;
+ gint i;
+
+ g_return_val_if_fail (GAIL_IS_COMBO_BOX (obj), NULL);
+
+ name = ATK_OBJECT_CLASS (gail_combo_box_parent_class)->get_name (obj);
+ if (name)
+ return name;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ combo_box = GTK_COMBO_BOX (widget);
+ gail_combo_box = GAIL_COMBO_BOX (obj);
+ if (gtk_combo_box_get_active_iter (combo_box, &iter))
+ {
+ model = gtk_combo_box_get_model (combo_box);
+ n_columns = gtk_tree_model_get_n_columns (model);
+ for (i = 0; i < n_columns; i++)
+ {
+ GValue value = { 0, };
+
+ gtk_tree_model_get_value (model, &iter, i, &value);
+ if (G_VALUE_HOLDS_STRING (&value))
+ {
+ if (gail_combo_box->name) g_free (gail_combo_box->name);
+ gail_combo_box->name = g_strdup ((gchar *)
+ g_value_get_string (&value));
+ g_value_unset (&value);
+ break;
+ }
+ else
+ g_value_unset (&value);
+ }
+ }
+ return gail_combo_box->name;
+}
+
+/*
+ * The children of a GailComboBox are the list of items and the entry field
+ * if it is editable.
+ */
+static gint
+gail_combo_box_get_n_children (AtkObject* obj)
+{
+ gint n_children = 0;
+ GtkWidget *widget;
+
+ g_return_val_if_fail (GAIL_IS_COMBO_BOX (obj), 0);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return 0;
+
+ n_children++;
+ if (gtk_combo_box_get_has_entry (GTK_COMBO_BOX (widget)))
+ n_children ++;
+
+ return n_children;
+}
+
+static AtkObject*
+gail_combo_box_ref_child (AtkObject *obj,
+ gint i)
+{
+ GtkWidget *widget;
+ AtkObject *child;
+ GailComboBox *box;
+
+ g_return_val_if_fail (GAIL_IS_COMBO_BOX (obj), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ if (i == 0)
+ {
+ child = gtk_combo_box_get_popup_accessible (GTK_COMBO_BOX (widget));
+ box = GAIL_COMBO_BOX (obj);
+ if (box->popup_set == FALSE)
+ {
+ atk_object_set_parent (child, obj);
+ box->popup_set = TRUE;
+ }
+ }
+ else if (i == 1 && gtk_combo_box_get_has_entry (GTK_COMBO_BOX (widget)))
+ {
+ child = gtk_widget_get_accessible (gtk_bin_get_child (GTK_BIN (widget)));
+ }
+ else
+ {
+ return NULL;
+ }
+ return g_object_ref (child);
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ iface->do_action = gail_combo_box_do_action;
+ iface->get_n_actions = gail_combo_box_get_n_actions;
+ iface->get_description = gail_combo_box_get_description;
+ iface->get_keybinding = gail_combo_box_get_keybinding;
+ iface->get_name = gail_combo_box_action_get_name;
+ iface->set_description = gail_combo_box_set_description;
+}
+
+static gboolean
+gail_combo_box_do_action (AtkAction *action,
+ gint i)
+{
+ GailComboBox *combo_box;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ if (!gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ combo_box = GAIL_COMBO_BOX (action);
+ if (i == 0)
+ {
+ if (combo_box->action_idle_handler)
+ return FALSE;
+
+ combo_box->action_idle_handler = gdk_threads_add_idle (idle_do_action, combo_box);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+idle_do_action (gpointer data)
+{
+ GtkComboBox *combo_box;
+ GtkWidget *widget;
+ GailComboBox *gail_combo_box;
+ AtkObject *popup;
+ gboolean do_popup;
+
+ gail_combo_box = GAIL_COMBO_BOX (data);
+ gail_combo_box->action_idle_handler = 0;
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gail_combo_box));
+
+ if (widget == NULL || /* State is defunct */
+ !gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ combo_box = GTK_COMBO_BOX (widget);
+
+ popup = gtk_combo_box_get_popup_accessible (combo_box);
+ do_popup = !gtk_widget_get_mapped (gtk_accessible_get_widget (GTK_ACCESSIBLE (popup)));
+ if (do_popup)
+ gtk_combo_box_popup (combo_box);
+ else
+ gtk_combo_box_popdown (combo_box);
+
+ return FALSE;
+}
+
+static gint
+gail_combo_box_get_n_actions (AtkAction *action)
+{
+ /*
+ * The default behavior of a combo_box box is to have one action -
+ */
+ return 1;
+}
+
+static const gchar*
+gail_combo_box_get_description (AtkAction *action,
+ gint i)
+{
+ if (i == 0)
+ {
+ GailComboBox *combo_box;
+
+ combo_box = GAIL_COMBO_BOX (action);
+ return combo_box->press_description;
+ }
+ else
+ return NULL;
+}
+
+static const gchar*
+gail_combo_box_get_keybinding (AtkAction *action,
+ gint i)
+{
+ GailComboBox *combo_box;
+ gchar *return_value = NULL;
+ switch (i)
+ {
+ case 0:
+ {
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkRelationSet *set;
+ AtkRelation *relation;
+ GPtrArray *target;
+ gpointer target_object;
+ guint key_val;
+
+ combo_box = GAIL_COMBO_BOX (action);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (combo_box));
+ if (widget == NULL)
+ return NULL;
+ set = atk_object_ref_relation_set (ATK_OBJECT (action));
+ if (!set)
+ return NULL;
+ label = NULL;
+ relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
+ if (relation)
+ {
+ target = atk_relation_get_target (relation);
+ target_object = g_ptr_array_index (target, 0);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
+ }
+ g_object_unref (set);
+ if (GTK_IS_LABEL (label))
+ {
+ key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
+ if (key_val != GDK_KEY_VoidSymbol)
+ return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
+ }
+ g_free (combo_box->press_keybinding);
+ combo_box->press_keybinding = return_value;
+ break;
+ }
+ default:
+ break;
+ }
+ return return_value;
+}
+
+
+static const gchar*
+gail_combo_box_action_get_name (AtkAction *action,
+ gint i)
+{
+ if (i == 0)
+ return "press";
+ else
+ return NULL;
+}
+
+static gboolean
+gail_combo_box_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc)
+{
+ if (i == 0)
+ {
+ GailComboBox *combo_box;
+
+ combo_box = GAIL_COMBO_BOX (action);
+ g_free (combo_box->press_description);
+ combo_box->press_description = g_strdup (desc);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ iface->add_selection = gail_combo_box_add_selection;
+ iface->clear_selection = gail_combo_box_clear_selection;
+ iface->ref_selection = gail_combo_box_ref_selection;
+ iface->get_selection_count = gail_combo_box_get_selection_count;
+ iface->is_child_selected = gail_combo_box_is_child_selected;
+ iface->remove_selection = gail_combo_box_remove_selection;
+ /*
+ * select_all_selection does not make sense for a combo_box
+ * so no implementation is provided.
+ */
+}
+
+static gboolean
+gail_combo_box_add_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkComboBox *combo_box;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ combo_box = GTK_COMBO_BOX (widget);
+
+ gtk_combo_box_set_active (combo_box, i);
+ return TRUE;
+}
+
+static gboolean
+gail_combo_box_clear_selection (AtkSelection *selection)
+{
+ GtkComboBox *combo_box;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ combo_box = GTK_COMBO_BOX (widget);
+
+ gtk_combo_box_set_active (combo_box, -1);
+ return TRUE;
+}
+
+static AtkObject*
+gail_combo_box_ref_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkComboBox *combo_box;
+ GtkWidget *widget;
+ AtkObject *obj;
+ gint index;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ combo_box = GTK_COMBO_BOX (widget);
+
+ /*
+ * A combo_box box can have only one selection.
+ */
+ if (i != 0)
+ return NULL;
+
+ obj = gtk_combo_box_get_popup_accessible (combo_box);
+ index = gtk_combo_box_get_active (combo_box);
+ return atk_object_ref_accessible_child (obj, index);
+}
+
+static gint
+gail_combo_box_get_selection_count (AtkSelection *selection)
+{
+ GtkComboBox *combo_box;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return 0;
+
+ combo_box = GTK_COMBO_BOX (widget);
+
+ return (gtk_combo_box_get_active (combo_box) == -1) ? 0 : 1;
+}
+
+static gboolean
+gail_combo_box_is_child_selected (AtkSelection *selection,
+ gint i)
+{
+ GtkComboBox *combo_box;
+ gint j;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ combo_box = GTK_COMBO_BOX (widget);
+
+ j = gtk_combo_box_get_active (combo_box);
+
+ return (j == i);
+}
+
+static gboolean
+gail_combo_box_remove_selection (AtkSelection *selection,
+ gint i)
+{
+ if (atk_selection_is_child_selected (selection, i))
+ atk_selection_clear_selection (selection);
+
+ return TRUE;
+}
+
+static void
+gail_combo_box_finalize (GObject *object)
+{
+ GailComboBox *combo_box = GAIL_COMBO_BOX (object);
+
+ g_free (combo_box->press_description);
+ g_free (combo_box->press_keybinding);
+ g_free (combo_box->name);
+ if (combo_box->action_idle_handler)
+ {
+ g_source_remove (combo_box->action_idle_handler);
+ combo_box->action_idle_handler = 0;
+ }
+ G_OBJECT_CLASS (gail_combo_box_parent_class)->finalize (object);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2004 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_COMBO_BOX_H__
+#define __GAIL_COMBO_BOX_H__
+
+#include "gailcontainer.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_COMBO_BOX (gail_combo_box_get_type ())
+#define GAIL_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_COMBO_BOX, GailComboBox))
+#define GAIL_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_COMBO_BOX, GailComboBoxClass))
+#define GAIL_IS_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_COMBO_BOX))
+#define GAIL_IS_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_COMBO_BOX))
+#define GAIL_COMBO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_COMBO_BOX, GailComboBoxClass))
+
+typedef struct _GailComboBox GailComboBox;
+typedef struct _GailComboBoxClass GailComboBoxClass;
+
+struct _GailComboBox
+{
+ GailContainer parent;
+
+ gchar *press_keybinding;
+ gchar *press_description;
+ guint action_idle_handler;
+
+ gchar *name;
+ gint old_selection;
+ gboolean popup_set;
+};
+
+GType gail_combo_box_get_type (void);
+
+struct _GailComboBoxClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_COMBO_BOX_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailcontainer.h"
+
+static void gail_container_class_init (GailContainerClass *klass);
+static void gail_container_init (GailContainer *container);
+
+static gint gail_container_get_n_children (AtkObject *obj);
+static AtkObject* gail_container_ref_child (AtkObject *obj,
+ gint i);
+static gint gail_container_add_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data);
+static gint gail_container_remove_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data);
+static gint gail_container_real_add_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data);
+static gint gail_container_real_remove_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data);
+
+static void gail_container_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static void gail_container_finalize (GObject *object);
+
+G_DEFINE_TYPE (GailContainer, gail_container, GAIL_TYPE_WIDGET)
+
+static void
+gail_container_class_init (GailContainerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = gail_container_finalize;
+
+ class->get_n_children = gail_container_get_n_children;
+ class->ref_child = gail_container_ref_child;
+ class->initialize = gail_container_real_initialize;
+
+ klass->add_gtk = gail_container_real_add_gtk;
+ klass->remove_gtk = gail_container_real_remove_gtk;
+}
+
+static void
+gail_container_init (GailContainer *container)
+{
+ container->children = NULL;
+}
+
+static gint
+gail_container_get_n_children (AtkObject* obj)
+{
+ GtkWidget *widget;
+ GList *children;
+ gint count = 0;
+
+ g_return_val_if_fail (GAIL_IS_CONTAINER (obj), count);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return 0;
+
+ children = gtk_container_get_children (GTK_CONTAINER(widget));
+ count = g_list_length (children);
+ g_list_free (children);
+
+ return count;
+}
+
+static AtkObject*
+gail_container_ref_child (AtkObject *obj,
+ gint i)
+{
+ GList *children, *tmp_list;
+ AtkObject *accessible;
+ GtkWidget *widget;
+
+ g_return_val_if_fail (GAIL_IS_CONTAINER (obj), NULL);
+ g_return_val_if_fail ((i >= 0), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return NULL;
+
+ children = gtk_container_get_children (GTK_CONTAINER (widget));
+ tmp_list = g_list_nth (children, i);
+ if (!tmp_list)
+ {
+ g_list_free (children);
+ return NULL;
+ }
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
+
+ g_list_free (children);
+ g_object_ref (accessible);
+ return accessible;
+}
+
+static gint
+gail_container_add_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data)
+{
+ GailContainer *gail_container = GAIL_CONTAINER (data);
+ GailContainerClass *klass;
+
+ klass = GAIL_CONTAINER_GET_CLASS (gail_container);
+
+ if (klass->add_gtk)
+ return klass->add_gtk (container, widget, data);
+ else
+ return 1;
+}
+
+static gint
+gail_container_remove_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data)
+{
+ GailContainer *gail_container = GAIL_CONTAINER (data);
+ GailContainerClass *klass;
+
+ klass = GAIL_CONTAINER_GET_CLASS (gail_container);
+
+ if (klass->remove_gtk)
+ return klass->remove_gtk (container, widget, data);
+ else
+ return 1;
+}
+
+static gint
+gail_container_real_add_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data)
+{
+ AtkObject* atk_parent = ATK_OBJECT (data);
+ AtkObject* atk_child = gtk_widget_get_accessible (widget);
+ GailContainer *gail_container = GAIL_CONTAINER (atk_parent);
+ gint index;
+
+ g_object_notify (G_OBJECT (atk_child), "accessible_parent");
+
+ g_list_free (gail_container->children);
+ gail_container->children = gtk_container_get_children (container);
+ index = g_list_index (gail_container->children, widget);
+ g_signal_emit_by_name (atk_parent, "children_changed::add",
+ index, atk_child, NULL);
+
+ return 1;
+}
+
+static gint
+gail_container_real_remove_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data)
+{
+ AtkPropertyValues values = { NULL };
+ AtkObject* atk_parent;
+ AtkObject *atk_child;
+ GailContainer *gail_container;
+ gint index;
+
+ atk_parent = ATK_OBJECT (data);
+ atk_child = gtk_widget_get_accessible (widget);
+
+ if (atk_child)
+ {
+ g_value_init (&values.old_value, G_TYPE_POINTER);
+ g_value_set_pointer (&values.old_value, atk_parent);
+
+ values.property_name = "accessible-parent";
+
+ g_object_ref (atk_child);
+ g_signal_emit_by_name (atk_child,
+ "property_change::accessible-parent", &values, NULL);
+ g_object_unref (atk_child);
+ }
+ gail_container = GAIL_CONTAINER (atk_parent);
+ index = g_list_index (gail_container->children, widget);
+ g_list_free (gail_container->children);
+ gail_container->children = gtk_container_get_children (container);
+ if (index >= 0 && index <= g_list_length (gail_container->children))
+ g_signal_emit_by_name (atk_parent, "children_changed::remove",
+ index, atk_child, NULL);
+
+ return 1;
+}
+
+static void
+gail_container_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GailContainer *container = GAIL_CONTAINER (obj);
+
+ ATK_OBJECT_CLASS (gail_container_parent_class)->initialize (obj, data);
+
+ container->children = gtk_container_get_children (GTK_CONTAINER (data));
+
+ g_signal_connect (data, "add",
+ G_CALLBACK (gail_container_add_gtk),
+ obj);
+ g_signal_connect (data, "remove",
+ G_CALLBACK (gail_container_remove_gtk),
+ obj);
+
+ if (GTK_IS_TOOLBAR (data))
+ obj->role = ATK_ROLE_TOOL_BAR;
+ else if (GTK_IS_VIEWPORT (data))
+ obj->role = ATK_ROLE_VIEWPORT;
+ else
+ obj->role = ATK_ROLE_PANEL;
+}
+
+static void
+gail_container_finalize (GObject *object)
+{
+ GailContainer *container = GAIL_CONTAINER (object);
+
+ g_list_free (container->children);
+ G_OBJECT_CLASS (gail_container_parent_class)->finalize (object);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_CONTAINER_H__
+#define __GAIL_CONTAINER_H__
+
+#include "gailwidget.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_CONTAINER (gail_container_get_type ())
+#define GAIL_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CONTAINER, GailContainer))
+#define GAIL_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CONTAINER, GailContainerClass))
+#define GAIL_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CONTAINER))
+#define GAIL_IS_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CONTAINER))
+#define GAIL_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CONTAINER, GailContainerClass))
+
+typedef struct _GailContainer GailContainer;
+typedef struct _GailContainerClass GailContainerClass;
+
+struct _GailContainer
+{
+ GailWidget parent;
+
+ /*
+ * Cached list of children
+ */
+ GList *children;
+};
+
+GType gail_container_get_type (void);
+
+struct _GailContainerClass
+{
+ GailWidgetClass parent_class;
+
+ gint (*add_gtk) (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data);
+ gint (*remove_gtk) (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data);
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_CONTAINER_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailcontainercell.h"
+
+static void gail_container_cell_class_init (GailContainerCellClass *klass);
+static void gail_container_cell_init (GailContainerCell *cell);
+static void gail_container_cell_finalize (GObject *obj);
+
+
+static void _gail_container_cell_recompute_child_indices
+ (GailContainerCell *container);
+
+static void gail_container_cell_refresh_child_index (GailCell *cell);
+
+static gint gail_container_cell_get_n_children (AtkObject *obj);
+
+static AtkObject* gail_container_cell_ref_child (AtkObject *obj,
+ gint child);
+
+G_DEFINE_TYPE (GailContainerCell, gail_container_cell, GAIL_TYPE_CELL)
+
+static void
+gail_container_cell_class_init (GailContainerCellClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS(klass);
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+
+ g_object_class->finalize = gail_container_cell_finalize;
+
+ class->get_n_children = gail_container_cell_get_n_children;
+ class->ref_child = gail_container_cell_ref_child;
+}
+
+static void
+gail_container_cell_init (GailContainerCell *cell)
+{
+}
+
+GailContainerCell *
+gail_container_cell_new (void)
+{
+ GObject *object;
+ AtkObject *atk_object;
+ GailContainerCell *container;
+
+ object = g_object_new (GAIL_TYPE_CONTAINER_CELL, NULL);
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ atk_object = ATK_OBJECT (object);
+ atk_object->role = ATK_ROLE_TABLE_CELL;
+
+ container = GAIL_CONTAINER_CELL(object);
+ container->children = NULL;
+ container->NChildren = 0;
+ return container;
+}
+
+static void
+gail_container_cell_finalize (GObject *obj)
+{
+ GailContainerCell *container = GAIL_CONTAINER_CELL (obj);
+ GList *list;
+
+ list = container->children;
+ while (list)
+ {
+ g_object_unref (list->data);
+ list = list->next;
+ }
+ g_list_free (container->children);
+
+ G_OBJECT_CLASS (gail_container_cell_parent_class)->finalize (obj);
+}
+
+
+void
+gail_container_cell_add_child (GailContainerCell *container,
+ GailCell *child)
+{
+ gint child_index;
+
+ g_return_if_fail (GAIL_IS_CONTAINER_CELL(container));
+ g_return_if_fail (GAIL_IS_CELL(child));
+
+ child_index = container->NChildren++;
+ container->children = g_list_append (container->children, (gpointer) child);
+ child->index = child_index;
+ atk_object_set_parent (ATK_OBJECT (child), ATK_OBJECT (container));
+ child->refresh_index = gail_container_cell_refresh_child_index;
+}
+
+
+void
+gail_container_cell_remove_child (GailContainerCell *container,
+ GailCell *child)
+{
+ g_return_if_fail (GAIL_IS_CONTAINER_CELL(container));
+ g_return_if_fail (GAIL_IS_CELL(child));
+ g_return_if_fail (container->NChildren > 0);
+
+ container->children = g_list_remove (container->children, (gpointer) child);
+ _gail_container_cell_recompute_child_indices (container);
+ container->NChildren--;
+}
+
+
+static void
+_gail_container_cell_recompute_child_indices (GailContainerCell *container)
+{
+ gint cur_index = 0;
+ GList *temp_list;
+
+ g_return_if_fail (GAIL_IS_CONTAINER_CELL(container));
+
+ for (temp_list = container->children; temp_list; temp_list = temp_list->next)
+ {
+ GAIL_CELL(temp_list->data)->index = cur_index;
+ cur_index++;
+ }
+}
+
+
+static void
+gail_container_cell_refresh_child_index (GailCell *cell)
+{
+ GailContainerCell *container;
+ g_return_if_fail (GAIL_IS_CELL(cell));
+ container = GAIL_CONTAINER_CELL (atk_object_get_parent (ATK_OBJECT(cell)));
+ g_return_if_fail (GAIL_IS_CONTAINER_CELL (container));
+ _gail_container_cell_recompute_child_indices (container);
+}
+
+
+
+static gint
+gail_container_cell_get_n_children (AtkObject *obj)
+{
+ GailContainerCell *cell;
+ g_return_val_if_fail (GAIL_IS_CONTAINER_CELL(obj), 0);
+ cell = GAIL_CONTAINER_CELL(obj);
+ return cell->NChildren;
+}
+
+
+static AtkObject *
+gail_container_cell_ref_child (AtkObject *obj,
+ gint child)
+{
+ GailContainerCell *cell;
+ GList *list_node;
+
+ g_return_val_if_fail (GAIL_IS_CONTAINER_CELL(obj), NULL);
+ cell = GAIL_CONTAINER_CELL(obj);
+
+ list_node = g_list_nth (cell->children, child);
+ if (!list_node)
+ return NULL;
+
+ return g_object_ref (ATK_OBJECT (list_node->data));
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_CONTAINER_CELL_H__
+#define __GAIL_CONTAINER_CELL_H__
+
+#include <atk/atk.h>
+#include "gailcell.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_CONTAINER_CELL (gail_container_cell_get_type ())
+#define GAIL_CONTAINER_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CONTAINER_CELL, GailContainerCell))
+#define GAIL_CONTAINER_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CONTAINER_CELL, GailContainerCellClass))
+#define GAIL_IS_CONTAINER_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CONTAINER_CELL))
+#define GAIL_IS_CONTAINER_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CONTAINER_CELL))
+#define GAIL_CONTAINER_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CONTAINER_CELL, GailContainerCellClass))
+
+typedef struct _GailContainerCell GailContainerCell;
+typedef struct _GailContainerCellClass GailContainerCellClass;
+
+struct _GailContainerCell
+{
+ GailCell parent;
+ GList *children;
+ gint NChildren;
+};
+
+GType gail_container_cell_get_type (void);
+
+struct _GailContainerCellClass
+{
+ GailCellClass parent_class;
+};
+
+GailContainerCell *
+gail_container_cell_new (void);
+
+void
+gail_container_cell_add_child (GailContainerCell *container,
+ GailCell *child);
+
+void
+gail_container_cell_remove_child (GailContainerCell *container,
+ GailCell *child);
+
+G_END_DECLS
+
+#endif /* __GAIL_TREE_VIEW_TEXT_CELL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "gailentry.h"
+#include "gailcombobox.h"
+#include <libgail-util/gailmisc.h>
+
+static void gail_entry_class_init (GailEntryClass *klass);
+static void gail_entry_init (GailEntry *entry);
+static void gail_entry_real_initialize (AtkObject *obj,
+ gpointer data);
+static void text_setup (GailEntry *entry,
+ GtkEntry *gtk_entry);
+static void gail_entry_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+static void gail_entry_finalize (GObject *object);
+
+static gint gail_entry_get_index_in_parent (AtkObject *accessible);
+
+/* atkobject.h */
+
+static AtkStateSet* gail_entry_ref_state_set (AtkObject *accessible);
+static AtkAttributeSet* gail_entry_get_attributes (AtkObject *accessible);
+
+/* atktext.h */
+
+static void atk_text_interface_init (AtkTextIface *iface);
+
+static gchar* gail_entry_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gunichar gail_entry_get_character_at_offset
+ (AtkText *text,
+ gint offset);
+static gchar* gail_entry_get_text_before_offset(AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_entry_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_entry_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gint gail_entry_get_caret_offset (AtkText *text);
+static gboolean gail_entry_set_caret_offset (AtkText *text,
+ gint offset);
+static gint gail_entry_get_n_selections (AtkText *text);
+static gchar* gail_entry_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_offset,
+ gint *end_offset);
+static gboolean gail_entry_add_selection (AtkText *text,
+ gint start_offset,
+ gint end_offset);
+static gboolean gail_entry_remove_selection (AtkText *text,
+ gint selection_num);
+static gboolean gail_entry_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_offset,
+ gint end_offset);
+static gint gail_entry_get_character_count (AtkText *text);
+static AtkAttributeSet * gail_entry_get_run_attributes
+ (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet * gail_entry_get_default_attributes
+ (AtkText *text);
+static void gail_entry_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static gint gail_entry_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+/* atkeditabletext.h */
+
+static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
+static void gail_entry_set_text_contents (AtkEditableText *text,
+ const gchar *string);
+static void gail_entry_insert_text (AtkEditableText *text,
+ const gchar *string,
+ gint length,
+ gint *position);
+static void gail_entry_copy_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+static void gail_entry_cut_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+static void gail_entry_delete_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+static void gail_entry_paste_text (AtkEditableText *text,
+ gint position);
+static void gail_entry_paste_received (GtkClipboard *clipboard,
+ const gchar *text,
+ gpointer data);
+
+
+/* Callbacks */
+
+static gboolean gail_entry_idle_notify_insert (gpointer data);
+static void gail_entry_notify_insert (GailEntry *entry);
+static void gail_entry_notify_delete (GailEntry *entry);
+static void _gail_entry_insert_text_cb (GtkEntry *entry,
+ gchar *arg1,
+ gint arg2,
+ gpointer arg3);
+static void _gail_entry_delete_text_cb (GtkEntry *entry,
+ gint arg1,
+ gint arg2);
+static void _gail_entry_changed_cb (GtkEntry *entry);
+static gboolean check_for_selection_change (GailEntry *entry,
+ GtkEntry *gtk_entry);
+
+static void atk_action_interface_init (AtkActionIface *iface);
+
+static gboolean gail_entry_do_action (AtkAction *action,
+ gint i);
+static gboolean idle_do_action (gpointer data);
+static gint gail_entry_get_n_actions (AtkAction *action);
+static const gchar* gail_entry_action_get_description (AtkAction *action,
+ gint i);
+static const gchar* gail_entry_get_keybinding (AtkAction *action,
+ gint i);
+static const gchar* gail_entry_action_get_name (AtkAction *action,
+ gint i);
+static gboolean gail_entry_action_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc);
+
+typedef struct _GailEntryPaste GailEntryPaste;
+
+struct _GailEntryPaste
+{
+ GtkEntry* entry;
+ gint position;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GailEntry, gail_entry, GAIL_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
+
+static void
+gail_entry_class_init (GailEntryClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailWidgetClass *widget_class;
+
+ widget_class = (GailWidgetClass*)klass;
+
+ gobject_class->finalize = gail_entry_finalize;
+
+ class->ref_state_set = gail_entry_ref_state_set;
+ class->get_index_in_parent = gail_entry_get_index_in_parent;
+ class->initialize = gail_entry_real_initialize;
+ class->get_attributes = gail_entry_get_attributes;
+
+ widget_class->notify_gtk = gail_entry_real_notify_gtk;
+}
+
+static void
+gail_entry_init (GailEntry *entry)
+{
+ entry->textutil = NULL;
+ entry->signal_name_insert = NULL;
+ entry->signal_name_delete = NULL;
+ entry->cursor_position = 0;
+ entry->selection_bound = 0;
+ entry->activate_description = NULL;
+ entry->activate_keybinding = NULL;
+}
+
+static void
+gail_entry_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkEntry *entry;
+ GailEntry *gail_entry;
+ gint start_pos, end_pos;
+
+ ATK_OBJECT_CLASS (gail_entry_parent_class)->initialize (obj, data);
+
+ gail_entry = GAIL_ENTRY (obj);
+ gail_entry->textutil = gail_text_util_new ();
+
+ g_assert (GTK_IS_ENTRY (data));
+
+ entry = GTK_ENTRY (data);
+ text_setup (gail_entry, entry);
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
+ &start_pos, &end_pos);
+ gail_entry->cursor_position = end_pos;
+ gail_entry->selection_bound = start_pos;
+
+ /* Set up signal callbacks */
+ g_signal_connect (data, "insert-text",
+ G_CALLBACK (_gail_entry_insert_text_cb), NULL);
+ g_signal_connect (data, "delete-text",
+ G_CALLBACK (_gail_entry_delete_text_cb), NULL);
+ g_signal_connect (data, "changed",
+ G_CALLBACK (_gail_entry_changed_cb), NULL);
+
+ if (gtk_entry_get_visibility (entry))
+ obj->role = ATK_ROLE_TEXT;
+ else
+ obj->role = ATK_ROLE_PASSWORD_TEXT;
+}
+
+static void
+gail_entry_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkWidget *widget;
+ AtkObject* atk_obj;
+ GtkEntry* gtk_entry;
+ GailEntry* entry;
+
+ widget = GTK_WIDGET (obj);
+ atk_obj = gtk_widget_get_accessible (widget);
+ gtk_entry = GTK_ENTRY (widget);
+ entry = GAIL_ENTRY (atk_obj);
+
+ if (strcmp (pspec->name, "cursor-position") == 0)
+ {
+ if (entry->insert_idle_handler == 0)
+ entry->insert_idle_handler = gdk_threads_add_idle (gail_entry_idle_notify_insert, entry);
+
+ if (check_for_selection_change (entry, gtk_entry))
+ g_signal_emit_by_name (atk_obj, "text_selection_changed");
+ /*
+ * The entry cursor position has moved so generate the signal.
+ */
+ g_signal_emit_by_name (atk_obj, "text_caret_moved",
+ entry->cursor_position);
+ }
+ else if (strcmp (pspec->name, "selection-bound") == 0)
+ {
+ if (entry->insert_idle_handler == 0)
+ entry->insert_idle_handler = gdk_threads_add_idle (gail_entry_idle_notify_insert, entry);
+
+ if (check_for_selection_change (entry, gtk_entry))
+ g_signal_emit_by_name (atk_obj, "text_selection_changed");
+ }
+ else if (strcmp (pspec->name, "editable") == 0)
+ {
+ gboolean value;
+
+ g_object_get (obj, "editable", &value, NULL);
+ atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE,
+ value);
+ }
+ else if (strcmp (pspec->name, "visibility") == 0)
+ {
+ gboolean visibility;
+ AtkRole new_role;
+
+ text_setup (entry, gtk_entry);
+ visibility = gtk_entry_get_visibility (gtk_entry);
+ new_role = visibility ? ATK_ROLE_TEXT : ATK_ROLE_PASSWORD_TEXT;
+ atk_object_set_role (atk_obj, new_role);
+ }
+ else if (strcmp (pspec->name, "invisible-char") == 0)
+ {
+ text_setup (entry, gtk_entry);
+ }
+ else if (strcmp (pspec->name, "editing-canceled") == 0)
+ {
+ if (entry->insert_idle_handler)
+ {
+ g_source_remove (entry->insert_idle_handler);
+ entry->insert_idle_handler = 0;
+ }
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_entry_parent_class)->notify_gtk (obj, pspec);
+}
+
+static void
+text_setup (GailEntry *entry,
+ GtkEntry *gtk_entry)
+{
+ if (gtk_entry_get_visibility (gtk_entry))
+ {
+ gail_text_util_text_setup (entry->textutil, gtk_entry_get_text (gtk_entry));
+ }
+ else
+ {
+ gunichar invisible_char;
+ GString *tmp_string = g_string_new (NULL);
+ gint ch_len;
+ gchar buf[7];
+ guint length;
+ gint i;
+
+ invisible_char = gtk_entry_get_invisible_char (gtk_entry);
+ if (invisible_char == 0)
+ invisible_char = ' ';
+
+ ch_len = g_unichar_to_utf8 (invisible_char, buf);
+ length = gtk_entry_get_text_length (gtk_entry);
+ for (i = 0; i < length; i++)
+ {
+ g_string_append_len (tmp_string, buf, ch_len);
+ }
+
+ gail_text_util_text_setup (entry->textutil, tmp_string->str);
+ g_string_free (tmp_string, TRUE);
+
+ }
+}
+
+static void
+gail_entry_finalize (GObject *object)
+{
+ GailEntry *entry = GAIL_ENTRY (object);
+
+ g_object_unref (entry->textutil);
+ g_free (entry->activate_description);
+ g_free (entry->activate_keybinding);
+ if (entry->action_idle_handler)
+ {
+ g_source_remove (entry->action_idle_handler);
+ entry->action_idle_handler = 0;
+ }
+ if (entry->insert_idle_handler)
+ {
+ g_source_remove (entry->insert_idle_handler);
+ entry->insert_idle_handler = 0;
+ }
+ G_OBJECT_CLASS (gail_entry_parent_class)->finalize (object);
+}
+
+static gint
+gail_entry_get_index_in_parent (AtkObject *accessible)
+{
+ /*
+ * If the parent widget is a combo box then the index is 1
+ * otherwise do the normal thing.
+ */
+ if (accessible->accessible_parent)
+ if (GAIL_IS_COMBO_BOX (accessible->accessible_parent))
+ return 1;
+
+ return ATK_OBJECT_CLASS (gail_entry_parent_class)->get_index_in_parent (accessible);
+}
+
+/* atkobject.h */
+
+static AtkStateSet*
+gail_entry_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GtkEntry *entry;
+ gboolean value;
+ GtkWidget *widget;
+
+ state_set = ATK_OBJECT_CLASS (gail_entry_parent_class)->ref_state_set (accessible);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ return state_set;
+
+ entry = GTK_ENTRY (widget);
+
+ g_object_get (G_OBJECT (entry), "editable", &value, NULL);
+ if (value)
+ atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
+ atk_state_set_add_state (state_set, ATK_STATE_SINGLE_LINE);
+
+ return state_set;
+}
+
+static AtkAttributeSet *
+gail_entry_get_attributes (AtkObject *accessible)
+{
+ GtkWidget *widget;
+ AtkAttributeSet *attributes;
+ AtkAttribute *placeholder_text;
+ const gchar *text;
+
+ attributes = ATK_OBJECT_CLASS (gail_entry_parent_class)->get_attributes (accessible);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ return attributes;
+
+ text = gtk_entry_get_placeholder_text (GTK_ENTRY (widget));
+ if (text == NULL)
+ return attributes;
+
+ placeholder_text = g_malloc (sizeof (AtkAttribute));
+ placeholder_text->name = g_strdup ("placeholder-text");
+ placeholder_text->value = g_strdup (text);
+
+ attributes = g_slist_append (attributes, placeholder_text);
+
+ return attributes;
+}
+
+/* atktext.h */
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_entry_get_text;
+ iface->get_character_at_offset = gail_entry_get_character_at_offset;
+ iface->get_text_before_offset = gail_entry_get_text_before_offset;
+ iface->get_text_at_offset = gail_entry_get_text_at_offset;
+ iface->get_text_after_offset = gail_entry_get_text_after_offset;
+ iface->get_caret_offset = gail_entry_get_caret_offset;
+ iface->set_caret_offset = gail_entry_set_caret_offset;
+ iface->get_character_count = gail_entry_get_character_count;
+ iface->get_n_selections = gail_entry_get_n_selections;
+ iface->get_selection = gail_entry_get_selection;
+ iface->add_selection = gail_entry_add_selection;
+ iface->remove_selection = gail_entry_remove_selection;
+ iface->set_selection = gail_entry_set_selection;
+ iface->get_run_attributes = gail_entry_get_run_attributes;
+ iface->get_default_attributes = gail_entry_get_default_attributes;
+ iface->get_character_extents = gail_entry_get_character_extents;
+ iface->get_offset_at_point = gail_entry_get_offset_at_point;
+}
+
+static gchar*
+gail_entry_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ return gail_text_util_get_substring (GAIL_ENTRY (text)->textutil, start_pos, end_pos);
+}
+
+static gchar*
+gail_entry_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkEntry *entry;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get Entry */
+ entry = GTK_ENTRY (widget);
+
+ return gail_text_util_get_text (GAIL_ENTRY (text)->textutil,
+ gtk_entry_get_layout (entry), GAIL_BEFORE_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_entry_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkEntry *entry;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get Entry */
+ entry = GTK_ENTRY (widget);
+
+ return gail_text_util_get_text (GAIL_ENTRY (text)->textutil,
+ gtk_entry_get_layout (entry), GAIL_AT_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_entry_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkEntry *entry;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get Entry */
+ entry = GTK_ENTRY (widget);
+
+ return gail_text_util_get_text (GAIL_ENTRY (text)->textutil,
+ gtk_entry_get_layout (entry), GAIL_AFTER_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gint
+gail_entry_get_character_count (AtkText *text)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ entry = GTK_ENTRY (widget);
+ return g_utf8_strlen (gtk_entry_get_text (entry), -1);
+}
+
+static gint
+gail_entry_get_caret_offset (AtkText *text)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ entry = GTK_ENTRY (widget);
+
+ return gtk_editable_get_position (GTK_EDITABLE (entry));
+}
+
+static gboolean
+gail_entry_set_caret_offset (AtkText *text, gint offset)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ entry = GTK_ENTRY (widget);
+
+ gtk_editable_set_position (GTK_EDITABLE (entry), offset);
+ return TRUE;
+}
+
+static AtkAttributeSet*
+gail_entry_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkEntry *entry;
+ AtkAttributeSet *at_set = NULL;
+ GtkTextDirection dir;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ entry = GTK_ENTRY (widget);
+
+ dir = gtk_widget_get_direction (widget);
+ if (dir == GTK_TEXT_DIR_RTL)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_DIRECTION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
+ }
+
+ at_set = gail_misc_layout_get_run_attributes (at_set,
+ gtk_entry_get_layout (entry),
+ (gchar*)gtk_entry_get_text (entry),
+ offset,
+ start_offset,
+ end_offset);
+ return at_set;
+}
+
+static AtkAttributeSet*
+gail_entry_get_default_attributes (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkEntry *entry;
+ AtkAttributeSet *at_set = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ entry = GTK_ENTRY (widget);
+
+ at_set = gail_misc_get_default_attributes (at_set,
+ gtk_entry_get_layout (entry),
+ widget);
+ return at_set;
+}
+
+static void
+gail_entry_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkEntry *entry;
+ PangoRectangle char_rect;
+ gint index, x_layout, y_layout;
+ const gchar *entry_text;
+ gint start_pos, end_pos;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ entry = GTK_ENTRY (widget);
+
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
+ &start_pos, &end_pos);
+ gtk_entry_get_layout_offsets (entry, &x_layout, &y_layout);
+ entry_text = gtk_entry_get_text (entry);
+
+ index = g_utf8_offset_to_pointer (entry_text, offset) - entry_text;
+
+ /* FIXME: entry->preedit cannot be accessed directly
+ cursor_index = g_utf8_offset_to_pointer (entry_text, end_pos) - entry_text;
+ if (index > cursor_index)
+ index += entry->preedit_length;
+ */
+ pango_layout_index_to_pos (gtk_entry_get_layout(entry), index, &char_rect);
+
+ gail_misc_get_extents_from_pango_rectangle (widget, &char_rect,
+ x_layout, y_layout, x, y, width, height, coords);
+}
+
+static gint
+gail_entry_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkEntry *entry;
+ gint index, x_layout, y_layout;
+ const gchar *entry_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ entry = GTK_ENTRY (widget);
+
+ gtk_entry_get_layout_offsets (entry, &x_layout, &y_layout);
+ entry_text = gtk_entry_get_text (entry);
+
+ index = gail_misc_get_index_at_point_in_layout (widget,
+ gtk_entry_get_layout(entry), x_layout, y_layout, x, y, coords);
+ if (index == -1)
+ {
+ if (coords == ATK_XY_SCREEN || coords == ATK_XY_WINDOW)
+ return g_utf8_strlen (entry_text, -1);
+
+ return index;
+ }
+ else
+ {
+ gint start_pos, end_pos;
+
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
+ &start_pos, &end_pos);
+ /* FIXME: entry->preedit_length cannot be accessed directly
+ cursor_index = g_utf8_offset_to_pointer (entry_text, end_pos) - entry_text;
+ if (index >= cursor_index && entry->preedit_length)
+ {
+ if (index >= cursor_index + entry->preedit_length)
+ index -= entry->preedit_length;
+ else
+ index = cursor_index;
+ }
+ */
+ return g_utf8_pointer_to_offset (entry_text, entry_text + index);
+ }
+}
+
+static gint
+gail_entry_get_n_selections (AtkText *text)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+ gint select_start, select_end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ entry = GTK_ENTRY (widget);
+
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &select_start,
+ &select_end);
+
+ if (select_start != select_end)
+ return 1;
+ else
+ return 0;
+}
+
+static gchar*
+gail_entry_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_pos,
+ gint *end_pos)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Only let the user get the selection if one is set, and if the
+ * selection_num is 0.
+ */
+ if (selection_num != 0)
+ return NULL;
+
+ entry = GTK_ENTRY (widget);
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), start_pos, end_pos);
+
+ if (*start_pos != *end_pos)
+ return gtk_editable_get_chars (GTK_EDITABLE (entry), *start_pos, *end_pos);
+ else
+ return NULL;
+}
+
+static gboolean
+gail_entry_add_selection (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+ gint select_start, select_end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ entry = GTK_ENTRY (widget);
+
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &select_start,
+ &select_end);
+
+ /* If there is already a selection, then don't allow another to be added,
+ * since GtkEntry only supports one selected region.
+ */
+ if (select_start == select_end)
+ {
+ gtk_editable_select_region (GTK_EDITABLE (entry), start_pos, end_pos);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+gail_entry_remove_selection (AtkText *text,
+ gint selection_num)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+ gint select_start, select_end, caret_pos;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ if (selection_num != 0)
+ return FALSE;
+
+ entry = GTK_ENTRY (widget);
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &select_start,
+ &select_end);
+
+ if (select_start != select_end)
+ {
+ /* Setting the start & end of the selected region to the caret position
+ * turns off the selection.
+ */
+ caret_pos = gtk_editable_get_position (GTK_EDITABLE (entry));
+ gtk_editable_select_region (GTK_EDITABLE (entry), caret_pos, caret_pos);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+gail_entry_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+ gint select_start, select_end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ /* Only let the user move the selection if one is set, and if the
+ * selection_num is 0
+ */
+ if (selection_num != 0)
+ return FALSE;
+
+ entry = GTK_ENTRY (widget);
+
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &select_start,
+ &select_end);
+
+ if (select_start != select_end)
+ {
+ gtk_editable_select_region (GTK_EDITABLE (entry), start_pos, end_pos);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+atk_editable_text_interface_init (AtkEditableTextIface *iface)
+{
+ iface->set_text_contents = gail_entry_set_text_contents;
+ iface->insert_text = gail_entry_insert_text;
+ iface->copy_text = gail_entry_copy_text;
+ iface->cut_text = gail_entry_cut_text;
+ iface->delete_text = gail_entry_delete_text;
+ iface->paste_text = gail_entry_paste_text;
+ iface->set_run_attributes = NULL;
+}
+
+static void
+gail_entry_set_text_contents (AtkEditableText *text,
+ const gchar *string)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+ GtkEditable *editable;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ entry = GTK_ENTRY (widget);
+ editable = GTK_EDITABLE (entry);
+ if (!gtk_editable_get_editable (editable))
+ return;
+
+ gtk_entry_set_text (entry, string);
+}
+
+static void
+gail_entry_insert_text (AtkEditableText *text,
+ const gchar *string,
+ gint length,
+ gint *position)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+ GtkEditable *editable;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ entry = GTK_ENTRY (widget);
+ editable = GTK_EDITABLE (entry);
+ if (!gtk_editable_get_editable (editable))
+ return;
+
+ gtk_editable_insert_text (editable, string, length, position);
+ gtk_editable_set_position (editable, *position);
+}
+
+static void
+gail_entry_copy_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+ GtkEditable *editable;
+ gchar *str;
+ GtkClipboard *clipboard;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ entry = GTK_ENTRY (widget);
+ editable = GTK_EDITABLE (entry);
+ str = gtk_editable_get_chars (editable, start_pos, end_pos);
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
+ GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, str, -1);
+}
+
+static void
+gail_entry_cut_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+ GtkEditable *editable;
+ gchar *str;
+ GtkClipboard *clipboard;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ entry = GTK_ENTRY (widget);
+ editable = GTK_EDITABLE (entry);
+ if (!gtk_editable_get_editable (editable))
+ return;
+ str = gtk_editable_get_chars (editable, start_pos, end_pos);
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
+ GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, str, -1);
+ gtk_editable_delete_text (editable, start_pos, end_pos);
+}
+
+static void
+gail_entry_delete_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkEntry *entry;
+ GtkWidget *widget;
+ GtkEditable *editable;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ entry = GTK_ENTRY (widget);
+ editable = GTK_EDITABLE (entry);
+ if (!gtk_editable_get_editable (editable))
+ return;
+
+ gtk_editable_delete_text (editable, start_pos, end_pos);
+}
+
+static void
+gail_entry_paste_text (AtkEditableText *text,
+ gint position)
+{
+ GtkWidget *widget;
+ GtkEditable *editable;
+ GailEntryPaste paste_struct;
+ GtkClipboard *clipboard;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ editable = GTK_EDITABLE (widget);
+ if (!gtk_editable_get_editable (editable))
+ return;
+ paste_struct.entry = GTK_ENTRY (widget);
+ paste_struct.position = position;
+
+ g_object_ref (paste_struct.entry);
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
+ GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_request_text (clipboard,
+ gail_entry_paste_received, &paste_struct);
+}
+
+static void
+gail_entry_paste_received (GtkClipboard *clipboard,
+ const gchar *text,
+ gpointer data)
+{
+ GailEntryPaste* paste_struct = (GailEntryPaste *)data;
+
+ if (text)
+ gtk_editable_insert_text (GTK_EDITABLE (paste_struct->entry), text, -1,
+ &(paste_struct->position));
+
+ g_object_unref (paste_struct->entry);
+}
+
+/* Callbacks */
+
+static gboolean
+gail_entry_idle_notify_insert (gpointer data)
+{
+ GailEntry *entry;
+
+ entry = GAIL_ENTRY (data);
+ entry->insert_idle_handler = 0;
+ gail_entry_notify_insert (entry);
+
+ return FALSE;
+}
+
+static void
+gail_entry_notify_insert (GailEntry *entry)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (entry));
+ if (gtk_entry_get_text_length (GTK_ENTRY (widget)) == 0)
+ return;
+
+ if (entry->signal_name_insert)
+ {
+ g_signal_emit_by_name (entry,
+ entry->signal_name_insert,
+ entry->position_insert,
+ entry->length_insert);
+ entry->signal_name_insert = NULL;
+ }
+}
+
+/* Note arg1 returns the character at the start of the insert.
+ * arg2 returns the number of characters inserted.
+ */
+static void
+_gail_entry_insert_text_cb (GtkEntry *entry,
+ gchar *arg1,
+ gint arg2,
+ gpointer arg3)
+{
+ AtkObject *accessible;
+ GailEntry *gail_entry;
+ gint *position = (gint *) arg3;
+
+ if (arg2 == 0)
+ return;
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (entry));
+ gail_entry = GAIL_ENTRY (accessible);
+ if (!gail_entry->signal_name_insert)
+ {
+ gail_entry->signal_name_insert = "text_changed::insert";
+ gail_entry->position_insert = *position;
+ gail_entry->length_insert = g_utf8_strlen(arg1, arg2);
+ }
+ /*
+ * The signal will be emitted when the cursor position is updated.
+ * or in an idle handler if it not updated.
+ */
+ if (gail_entry->insert_idle_handler == 0)
+ gail_entry->insert_idle_handler = gdk_threads_add_idle (gail_entry_idle_notify_insert, gail_entry);
+}
+
+static gunichar
+gail_entry_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GtkWidget *widget;
+ GailEntry *entry;
+ gchar *string;
+ gchar *index;
+ gunichar unichar;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return '\0';
+
+ entry = GAIL_ENTRY (text);
+ string = gail_text_util_get_substring (entry->textutil, 0, -1);
+ if (offset >= g_utf8_strlen (string, -1))
+ {
+ unichar = '\0';
+ }
+ else
+ {
+ index = g_utf8_offset_to_pointer (string, offset);
+
+ unichar = g_utf8_get_char(index);
+ }
+
+ g_free(string);
+ return unichar;
+}
+
+static void
+gail_entry_notify_delete (GailEntry *entry)
+{
+ if (entry->signal_name_delete)
+ {
+ g_signal_emit_by_name (entry,
+ entry->signal_name_delete,
+ entry->position_delete,
+ entry->length_delete);
+ entry->signal_name_delete = NULL;
+ }
+}
+
+/* Note arg1 returns the start of the delete range, arg2 returns the
+ * end of the delete range if multiple characters are deleted.
+ */
+static void
+_gail_entry_delete_text_cb (GtkEntry *entry,
+ gint arg1,
+ gint arg2)
+{
+ AtkObject *accessible;
+ GailEntry *gail_entry;
+
+ /*
+ * Zero length text deleted so ignore
+ */
+ if (arg2 - arg1 == 0)
+ return;
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (entry));
+ gail_entry = GAIL_ENTRY (accessible);
+ if (!gail_entry->signal_name_delete)
+ {
+ gail_entry->signal_name_delete = "text_changed::delete";
+ gail_entry->position_delete = arg1;
+ gail_entry->length_delete = arg2 - arg1;
+ }
+ gail_entry_notify_delete (gail_entry);
+}
+
+static void
+_gail_entry_changed_cb (GtkEntry *entry)
+{
+ AtkObject *accessible;
+ GailEntry *gail_entry;
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (entry));
+
+ gail_entry = GAIL_ENTRY (accessible);
+
+ text_setup (gail_entry, entry);
+}
+
+static gboolean
+check_for_selection_change (GailEntry *entry,
+ GtkEntry *gtk_entry)
+{
+ gboolean selected, ret_val = FALSE;
+ gint start_pos, end_pos;
+
+ selected = gtk_editable_get_selection_bounds (GTK_EDITABLE (gtk_entry),
+ &start_pos, &end_pos);
+ if (selected)
+ {
+ if (end_pos != entry->cursor_position ||
+ start_pos != entry->selection_bound)
+ /*
+ * This check is here as this function can be called
+ * for notification of selection_bound and current_pos.
+ * The values of current_pos and selection_bound may be the same
+ * for both notifications and we only want to generate one
+ * text_selection_changed signal.
+ */
+ ret_val = TRUE;
+ }
+ else
+ {
+ /* We had a selection */
+ ret_val = (entry->cursor_position != entry->selection_bound);
+ }
+ entry->cursor_position = end_pos;
+ entry->selection_bound = start_pos;
+
+ return ret_val;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ iface->do_action = gail_entry_do_action;
+ iface->get_n_actions = gail_entry_get_n_actions;
+ iface->get_description = gail_entry_action_get_description;
+ iface->get_keybinding = gail_entry_get_keybinding;
+ iface->get_name = gail_entry_action_get_name;
+ iface->set_description = gail_entry_action_set_description;
+}
+
+static gboolean
+gail_entry_do_action (AtkAction *action,
+ gint i)
+{
+ GailEntry *entry;
+ GtkWidget *widget;
+ gboolean return_value = TRUE;
+
+ entry = GAIL_ENTRY (action);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ if (!gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ switch (i)
+ {
+ case 0:
+ if (entry->action_idle_handler)
+ return_value = FALSE;
+ else
+ entry->action_idle_handler = gdk_threads_add_idle (idle_do_action, entry);
+ break;
+ default:
+ return_value = FALSE;
+ break;
+ }
+ return return_value;
+}
+
+static gboolean
+idle_do_action (gpointer data)
+{
+ GailEntry *entry;
+ GtkWidget *widget;
+
+ entry = GAIL_ENTRY (data);
+ entry->action_idle_handler = 0;
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (entry));
+ if (widget == NULL /* State is defunct */ ||
+ !gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ gtk_widget_activate (widget);
+
+ return FALSE;
+}
+
+static gint
+gail_entry_get_n_actions (AtkAction *action)
+{
+ return 1;
+}
+
+static const gchar*
+gail_entry_action_get_description (AtkAction *action,
+ gint i)
+{
+ GailEntry *entry;
+ const gchar *return_value;
+
+ entry = GAIL_ENTRY (action);
+ switch (i)
+ {
+ case 0:
+ return_value = entry->activate_description;
+ break;
+ default:
+ return_value = NULL;
+ break;
+ }
+ return return_value;
+}
+
+static const gchar*
+gail_entry_get_keybinding (AtkAction *action,
+ gint i)
+{
+ GailEntry *entry;
+ gchar *return_value = NULL;
+
+ entry = GAIL_ENTRY (action);
+ switch (i)
+ {
+ case 0:
+ {
+ /*
+ * We look for a mnemonic on the label
+ */
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkRelationSet *set;
+ AtkRelation *relation;
+ GPtrArray *target;
+ gpointer target_object;
+ guint key_val;
+
+ entry = GAIL_ENTRY (action);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (entry));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ /* Find labelled-by relation */
+
+ set = atk_object_ref_relation_set (ATK_OBJECT (action));
+ if (!set)
+ return NULL;
+ label = NULL;
+ relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
+ if (relation)
+ {
+ target = atk_relation_get_target (relation);
+
+ target_object = g_ptr_array_index (target, 0);
+ label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
+ }
+
+ g_object_unref (set);
+
+ if (GTK_IS_LABEL (label))
+ {
+ key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
+ if (key_val != GDK_KEY_VoidSymbol)
+ return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
+ }
+ g_free (entry->activate_keybinding);
+ entry->activate_keybinding = return_value;
+ break;
+ }
+ default:
+ break;
+ }
+ return return_value;
+}
+
+static const gchar*
+gail_entry_action_get_name (AtkAction *action,
+ gint i)
+{
+ const gchar *return_value;
+
+ switch (i)
+ {
+ case 0:
+ return_value = "activate";
+ break;
+ default:
+ return_value = NULL;
+ break;
+ }
+ return return_value;
+}
+
+static gboolean
+gail_entry_action_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc)
+{
+ GailEntry *entry;
+ gchar **value;
+
+ entry = GAIL_ENTRY (action);
+ switch (i)
+ {
+ case 0:
+ value = &entry->activate_description;
+ break;
+ default:
+ value = NULL;
+ break;
+ }
+
+ if (value)
+ {
+ g_free (*value);
+ *value = g_strdup (desc);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_ENTRY_H__
+#define __GAIL_ENTRY_H__
+
+#include "gailwidget.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_ENTRY (gail_entry_get_type ())
+#define GAIL_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_ENTRY, GailEntry))
+#define GAIL_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_ENTRY, GailEntryClass))
+#define GAIL_IS_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_ENTRY))
+#define GAIL_IS_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_ENTRY))
+#define GAIL_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_ENTRY, GailEntryClass))
+
+typedef struct _GailEntry GailEntry;
+typedef struct _GailEntryClass GailEntryClass;
+
+struct _GailEntry
+{
+ GailWidget parent;
+
+ GailTextUtil *textutil;
+ /*
+ * These fields store information about text changed
+ */
+ gchar *signal_name_insert;
+ gchar *signal_name_delete;
+ gint position_insert;
+ gint position_delete;
+ gint length_insert;
+ gint length_delete;
+ gint cursor_position;
+ gint selection_bound;
+
+ gchar *activate_description;
+ gchar *activate_keybinding;
+ guint action_idle_handler;
+ guint insert_idle_handler;
+};
+
+GType gail_entry_get_type (void);
+
+struct _GailEntryClass
+{
+ GailWidgetClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_ENTRY_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "gailexpander.h"
+#include <libgail-util/gailmisc.h>
+
+static void gail_expander_class_init (GailExpanderClass *klass);
+static void gail_expander_init (GailExpander *expander);
+
+static const gchar* gail_expander_get_name (AtkObject *obj);
+static gint gail_expander_get_n_children (AtkObject *obj)
+;
+static AtkObject* gail_expander_ref_child (AtkObject *obj,
+ gint i);
+
+static AtkStateSet* gail_expander_ref_state_set (AtkObject *obj);
+static void gail_expander_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+static void gail_expander_map_gtk (GtkWidget *widget,
+ gpointer data);
+
+static void gail_expander_real_initialize (AtkObject *obj,
+ gpointer data);
+static void gail_expander_finalize (GObject *object);
+static void gail_expander_init_textutil (GailExpander *expander,
+ GtkExpander *widget);
+static const gchar* gail_expander_get_full_text (GtkExpander *widget);
+
+static void atk_action_interface_init (AtkActionIface *iface);
+static gboolean gail_expander_do_action (AtkAction *action,
+ gint i);
+static gboolean idle_do_action (gpointer data);
+static gint gail_expander_get_n_actions(AtkAction *action);
+static const gchar* gail_expander_get_description
+ (AtkAction *action,
+ gint i);
+static const gchar* gail_expander_get_keybinding
+ (AtkAction *action,
+ gint i);
+static const gchar* gail_expander_action_get_name
+ (AtkAction *action,
+ gint i);
+static gboolean gail_expander_set_description
+ (AtkAction *action,
+ gint i,
+ const gchar *desc);
+
+/* atktext.h */
+static void atk_text_interface_init (AtkTextIface *iface);
+
+static gchar* gail_expander_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gunichar gail_expander_get_character_at_offset
+ (AtkText *text,
+ gint offset);
+static gchar* gail_expander_get_text_before_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_expander_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_expander_get_text_after_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gint gail_expander_get_character_count(AtkText *text);
+static void gail_expander_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static gint gail_expander_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static AtkAttributeSet* gail_expander_get_run_attributes
+ (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet* gail_expander_get_default_attributes
+ (AtkText *text);
+
+G_DEFINE_TYPE_WITH_CODE (GailExpander, gail_expander, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
+
+static void
+gail_expander_class_init (GailExpanderClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailWidgetClass *widget_class;
+
+ widget_class = (GailWidgetClass*)klass;
+ widget_class->notify_gtk = gail_expander_real_notify_gtk;
+
+ gobject_class->finalize = gail_expander_finalize;
+
+ class->get_name = gail_expander_get_name;
+ class->get_n_children = gail_expander_get_n_children;
+ class->ref_child = gail_expander_ref_child;
+ class->ref_state_set = gail_expander_ref_state_set;
+
+ class->initialize = gail_expander_real_initialize;
+}
+
+static void
+gail_expander_init (GailExpander *expander)
+{
+ expander->activate_description = NULL;
+ expander->activate_keybinding = NULL;
+ expander->action_idle_handler = 0;
+ expander->textutil = NULL;
+}
+
+static const gchar*
+gail_expander_get_name (AtkObject *obj)
+{
+ const gchar *name;
+ g_return_val_if_fail (GAIL_IS_EXPANDER (obj), NULL);
+
+ name = ATK_OBJECT_CLASS (gail_expander_parent_class)->get_name (obj);
+ if (name != NULL)
+ return name;
+ else
+ {
+ /*
+ * Get the text on the label
+ */
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ g_return_val_if_fail (GTK_IS_EXPANDER (widget), NULL);
+
+ return gail_expander_get_full_text (GTK_EXPANDER (widget));
+ }
+}
+
+static gint
+gail_expander_get_n_children (AtkObject* obj)
+{
+ GtkWidget *widget;
+ GList *children;
+ gint count = 0;
+
+ g_return_val_if_fail (GAIL_IS_CONTAINER (obj), count);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return 0;
+
+ children = gtk_container_get_children (GTK_CONTAINER(widget));
+ count = g_list_length (children);
+ g_list_free (children);
+
+ /* See if there is a label - if there is, reduce our count by 1
+ * since we don't want the label included with the children.
+ */
+ if (gtk_expander_get_label_widget (GTK_EXPANDER (widget)))
+ count -= 1;
+
+ return count;
+}
+
+static AtkObject*
+gail_expander_ref_child (AtkObject *obj,
+ gint i)
+{
+ GList *children, *tmp_list;
+ AtkObject *accessible;
+ GtkWidget *widget;
+ GtkWidget *label;
+ gint index;
+
+ g_return_val_if_fail (GAIL_IS_CONTAINER (obj), NULL);
+ g_return_val_if_fail ((i >= 0), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return NULL;
+
+ children = gtk_container_get_children (GTK_CONTAINER (widget));
+
+ /* See if there is a label - if there is, we need to skip it
+ * since we don't want the label included with the children.
+ */
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+ if (label) {
+ for (index = 0; index <= i; index++) {
+ tmp_list = g_list_nth (children, index);
+ if (label == GTK_WIDGET (tmp_list->data)) {
+ i += 1;
+ break;
+ }
+ }
+ }
+
+ tmp_list = g_list_nth (children, i);
+ if (!tmp_list)
+ {
+ g_list_free (children);
+ return NULL;
+ }
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
+
+ g_list_free (children);
+ g_object_ref (accessible);
+ return accessible;
+}
+
+static void
+gail_expander_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GailExpander *gail_expander = GAIL_EXPANDER (obj);
+ GtkWidget *expander;
+
+ ATK_OBJECT_CLASS (gail_expander_parent_class)->initialize (obj, data);
+
+ expander = GTK_WIDGET (data);
+ if (gtk_widget_get_mapped (expander))
+ gail_expander_init_textutil (gail_expander, GTK_EXPANDER (expander));
+ else
+ g_signal_connect (expander,
+ "map",
+ G_CALLBACK (gail_expander_map_gtk),
+ gail_expander);
+
+ obj->role = ATK_ROLE_TOGGLE_BUTTON;
+}
+
+static void
+gail_expander_map_gtk (GtkWidget *widget,
+ gpointer data)
+{
+ GailExpander *expander;
+
+ expander = GAIL_EXPANDER (data);
+ gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
+}
+
+static void
+gail_expander_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ AtkObject* atk_obj;
+ GtkExpander *expander;
+ GailExpander *gail_expander;
+
+ expander = GTK_EXPANDER (obj);
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (expander));
+;
+ if (strcmp (pspec->name, "label") == 0)
+ {
+ const gchar* label_text;
+
+
+ label_text = gail_expander_get_full_text (expander);
+
+ gail_expander = GAIL_EXPANDER (atk_obj);
+ if (gail_expander->textutil)
+ gail_text_util_text_setup (gail_expander->textutil, label_text);
+
+ if (atk_obj->name == NULL)
+ {
+ /*
+ * The label has changed so notify a change in accessible-name
+ */
+ g_object_notify (G_OBJECT (atk_obj), "accessible-name");
+ }
+ /*
+ * The label is the only property which can be changed
+ */
+ g_signal_emit_by_name (atk_obj, "visible_data_changed");
+ }
+ else if (strcmp (pspec->name, "expanded") == 0)
+ {
+ atk_object_notify_state_change (atk_obj, ATK_STATE_CHECKED,
+ gtk_expander_get_expanded (expander));
+ atk_object_notify_state_change (atk_obj, ATK_STATE_EXPANDED,
+ gtk_expander_get_expanded (expander));
+ g_signal_emit_by_name (atk_obj, "visible_data_changed");
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_expander_parent_class)->notify_gtk (obj, pspec);
+}
+
+static const gchar*
+gail_expander_get_full_text (GtkExpander *widget)
+{
+ GtkWidget *label_widget;
+
+ label_widget = gtk_expander_get_label_widget (widget);
+
+ if (!GTK_IS_LABEL (label_widget))
+ return NULL;
+
+ return gtk_label_get_text (GTK_LABEL (label_widget));
+}
+
+static void
+gail_expander_init_textutil (GailExpander *expander,
+ GtkExpander *widget)
+{
+ const gchar *label_text;
+
+ expander->textutil = gail_text_util_new ();
+ label_text = gail_expander_get_full_text (widget);
+ gail_text_util_text_setup (expander->textutil, label_text);
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ iface->do_action = gail_expander_do_action;
+ iface->get_n_actions = gail_expander_get_n_actions;
+ iface->get_description = gail_expander_get_description;
+ iface->get_keybinding = gail_expander_get_keybinding;
+ iface->get_name = gail_expander_action_get_name;
+ iface->set_description = gail_expander_set_description;
+}
+
+static gboolean
+gail_expander_do_action (AtkAction *action,
+ gint i)
+{
+ GtkWidget *widget;
+ GailExpander *expander;
+ gboolean return_value = TRUE;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ expander = GAIL_EXPANDER (action);
+ switch (i)
+ {
+ case 0:
+ if (expander->action_idle_handler)
+ return_value = FALSE;
+ else
+ expander->action_idle_handler = gdk_threads_add_idle (idle_do_action, expander);
+ break;
+ default:
+ return_value = FALSE;
+ break;
+ }
+ return return_value;
+}
+
+static gboolean
+idle_do_action (gpointer data)
+{
+ GtkWidget *widget;
+ GailExpander *gail_expander;
+
+ gail_expander = GAIL_EXPANDER (data);
+ gail_expander->action_idle_handler = 0;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gail_expander));
+ if (widget == NULL /* State is defunct */ ||
+ !gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ gtk_widget_activate (widget);
+
+ return FALSE;
+}
+
+static gint
+gail_expander_get_n_actions (AtkAction *action)
+{
+ return 1;
+}
+
+static const gchar*
+gail_expander_get_description (AtkAction *action,
+ gint i)
+{
+ GailExpander *expander;
+ const gchar *return_value;
+
+ expander = GAIL_EXPANDER (action);
+
+ switch (i)
+ {
+ case 0:
+ return_value = expander->activate_description;
+ break;
+ default:
+ return_value = NULL;
+ break;
+ }
+ return return_value;
+}
+
+static const gchar*
+gail_expander_get_keybinding (AtkAction *action,
+ gint i)
+{
+ GailExpander *expander;
+ gchar *return_value = NULL;
+
+ switch (i)
+ {
+ case 0:
+ {
+ /*
+ * We look for a mnemonic on the label
+ */
+ GtkWidget *widget;
+ GtkWidget *label;
+
+ expander = GAIL_EXPANDER (action);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (expander));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ g_return_val_if_fail (GTK_IS_EXPANDER (widget), NULL);
+
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+ if (GTK_IS_LABEL (label))
+ {
+ guint key_val;
+
+ key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
+ if (key_val != GDK_KEY_VoidSymbol)
+ return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
+ g_free (expander->activate_keybinding);
+ expander->activate_keybinding = return_value;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return return_value;
+}
+
+static const gchar*
+gail_expander_action_get_name (AtkAction *action,
+ gint i)
+{
+ const gchar *return_value;
+
+ switch (i)
+ {
+ case 0:
+ return_value = "activate";
+ break;
+ default:
+ return_value = NULL;
+ break;
+ }
+ return return_value;
+}
+
+static gboolean
+gail_expander_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc)
+{
+ GailExpander *expander;
+ gchar **value;
+
+ expander = GAIL_EXPANDER (action);
+
+ switch (i)
+ {
+ case 0:
+ value = &expander->activate_description;
+ break;
+ default:
+ value = NULL;
+ break;
+ }
+ if (value)
+ {
+ g_free (*value);
+ *value = g_strdup (desc);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static AtkStateSet*
+gail_expander_ref_state_set (AtkObject *obj)
+{
+ AtkStateSet *state_set;
+ GtkWidget *widget;
+ GtkExpander *expander;
+
+ state_set = ATK_OBJECT_CLASS (gail_expander_parent_class)->ref_state_set (obj);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+
+ if (widget == NULL)
+ return state_set;
+
+ expander = GTK_EXPANDER (widget);
+
+ atk_state_set_add_state (state_set, ATK_STATE_EXPANDABLE);
+
+ if (gtk_expander_get_expanded (expander)) {
+ atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
+ atk_state_set_add_state (state_set, ATK_STATE_EXPANDED);
+ }
+
+ return state_set;
+}
+
+/* atktext.h */
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_expander_get_text;
+ iface->get_character_at_offset = gail_expander_get_character_at_offset;
+ iface->get_text_before_offset = gail_expander_get_text_before_offset;
+ iface->get_text_at_offset = gail_expander_get_text_at_offset;
+ iface->get_text_after_offset = gail_expander_get_text_after_offset;
+ iface->get_character_count = gail_expander_get_character_count;
+ iface->get_character_extents = gail_expander_get_character_extents;
+ iface->get_offset_at_point = gail_expander_get_offset_at_point;
+ iface->get_run_attributes = gail_expander_get_run_attributes;
+ iface->get_default_attributes = gail_expander_get_default_attributes;
+}
+
+static gchar*
+gail_expander_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *widget;
+ GailExpander *expander;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ expander = GAIL_EXPANDER (text);
+ if (!expander->textutil)
+ gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
+
+ label_text = gail_expander_get_full_text (GTK_EXPANDER (widget));
+
+ if (label_text == NULL)
+ return NULL;
+ else
+ return gail_text_util_get_substring (expander->textutil,
+ start_pos, end_pos);
+}
+
+static gchar*
+gail_expander_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GailExpander *expander;
+ GtkWidget *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ expander = GAIL_EXPANDER (text);
+ if (!expander->textutil)
+ gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
+
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+ return gail_text_util_get_text (expander->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ GAIL_BEFORE_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_expander_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GailExpander *expander;
+ GtkWidget *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ expander = GAIL_EXPANDER (text);
+ if (!expander->textutil)
+ gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
+
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+ return gail_text_util_get_text (expander->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ GAIL_AT_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_expander_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GailExpander *expander;
+ GtkWidget *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ expander = GAIL_EXPANDER (text);
+ if (!expander->textutil)
+ gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
+
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+ return gail_text_util_get_text (expander->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ GAIL_AFTER_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gint
+gail_expander_get_character_count (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+ if (!GTK_IS_LABEL(label))
+ return 0;
+
+ return g_utf8_strlen (gtk_label_get_text (GTK_LABEL (label)), -1);
+}
+
+static void
+gail_expander_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ PangoRectangle char_rect;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+ if (!GTK_IS_LABEL(label))
+ return;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
+ pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
+
+ gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
+ x_layout, y_layout, x, y, width, height, coords);
+}
+
+static gint
+gail_expander_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+
+ if (!GTK_IS_LABEL(label))
+ return -1;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+
+ index = gail_misc_get_index_at_point_in_layout (label,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ x_layout, y_layout, x, y, coords);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ if (index == -1)
+ {
+ if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
+ return g_utf8_strlen (label_text, -1);
+
+ return index;
+ }
+ else
+ return g_utf8_pointer_to_offset (label_text, label_text + index);
+}
+
+static AtkAttributeSet*
+gail_expander_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkAttributeSet *at_set = NULL;
+ GtkJustification justify;
+ GtkTextDirection dir;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ /* Get values set for entire label, if any */
+ justify = gtk_label_get_justify (GTK_LABEL (label));
+ if (justify != GTK_JUSTIFY_CENTER)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_JUSTIFICATION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
+ }
+ dir = gtk_widget_get_direction (label);
+ if (dir == GTK_TEXT_DIR_RTL)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_DIRECTION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
+ }
+
+ at_set = gail_misc_layout_get_run_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ (gchar *) gtk_label_get_text (GTK_LABEL (label)),
+ offset,
+ start_offset,
+ end_offset);
+ return at_set;
+}
+
+static AtkAttributeSet*
+gail_expander_get_default_attributes (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkAttributeSet *at_set = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ at_set = gail_misc_get_default_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ widget);
+ return at_set;
+}
+
+static gunichar
+gail_expander_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ const gchar *string;
+ gchar *index;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return '\0';
+
+ label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
+
+ if (!GTK_IS_LABEL(label))
+ return '\0';
+ string = gtk_label_get_text (GTK_LABEL (label));
+ if (offset >= g_utf8_strlen (string, -1))
+ return '\0';
+ index = g_utf8_offset_to_pointer (string, offset);
+
+ return g_utf8_get_char (index);
+}
+
+static void
+gail_expander_finalize (GObject *object)
+{
+ GailExpander *expander = GAIL_EXPANDER (object);
+
+ g_free (expander->activate_description);
+ g_free (expander->activate_keybinding);
+ if (expander->action_idle_handler)
+ {
+ g_source_remove (expander->action_idle_handler);
+ expander->action_idle_handler = 0;
+ }
+ if (expander->textutil)
+ g_object_unref (expander->textutil);
+
+ G_OBJECT_CLASS (gail_expander_parent_class)->finalize (object);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_EXPANDER_H__
+#define __GAIL_EXPANDER_H__
+
+#include "gailcontainer.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_EXPANDER (gail_expander_get_type ())
+#define GAIL_EXPANDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_EXPANDER, GailExpander))
+#define GAIL_EXPANDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_EXPANDER, GailExpanderClass))
+#define GAIL_IS_EXPANDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_EXPANDER))
+#define GAIL_IS_EXPANDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_EXPANDER))
+#define GAIL_EXPANDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_EXPANDER, GailExpanderClass))
+
+typedef struct _GailExpander GailExpander;
+typedef struct _GailExpanderClass GailExpanderClass;
+
+struct _GailExpander
+{
+ GailContainer parent;
+
+ gchar *activate_description;
+ gchar *activate_keybinding;
+ guint action_idle_handler;
+
+ GailTextUtil *textutil;
+};
+
+GType gail_expander_get_type (void);
+
+struct _GailExpanderClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_EXPANDER_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002 Sun Microsystems Inc.
+ * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
+ * Copyright (C) 2007 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GAIL_FACTORY_H__
+#define _GAIL_FACTORY_H__
+
+#include <glib-object.h>
+#include <atk/atk.h>
+
+#define _GAIL_IMPLEMENT_FACTORY_CREATE_ACCESSIBLE(GAIL_TYPE, TYPE) \
+{ \
+ AtkObject *accessible; \
+\
+ g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object, TYPE), NULL); \
+\
+ accessible = g_object_new (GAIL_TYPE, NULL); \
+ atk_object_initialize (accessible, object); \
+\
+ return accessible; \
+}
+
+#define _GAIL_IMPLEMENT_FACTORY_BEGIN(GAIL_TYPE, TypeName, type_name) \
+\
+static GType \
+type_name##_factory_get_accessible_type (void) \
+{ \
+ return GAIL_TYPE; \
+} \
+\
+static AtkObject* \
+type_name##_factory_create_accessible (GObject *object) \
+{
+
+#define _GAIL_IMPLEMENT_FACTORY_END(GAIL_TYPE, TypeName, type_name) \
+} \
+\
+static void \
+type_name##_factory_class_init (AtkObjectFactoryClass *klass) \
+{ \
+ klass->create_accessible = type_name ## _factory_create_accessible; \
+ klass->get_accessible_type = type_name ## _factory_get_accessible_type;\
+} \
+\
+GType \
+type_name##_factory_get_type (void) \
+{ \
+ static volatile gsize g_define_type_id__volatile = 0; \
+ if (g_once_init_enter (&g_define_type_id__volatile)) \
+ { \
+ GType g_define_type_id = \
+ g_type_register_static_simple (ATK_TYPE_OBJECT_FACTORY, \
+ g_intern_static_string (#TypeName "Factory"), \
+ sizeof (AtkObjectFactoryClass), \
+ (GClassInitFunc) type_name##_factory_class_init, \
+ sizeof (AtkObjectFactory), \
+ (GInstanceInitFunc) NULL, \
+ (GTypeFlags) 0); \
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
+ } \
+ return g_define_type_id__volatile; \
+}
+
+/* Implements a AtkObjectFactory creating accessibles of type
+ * @GAIL_TYPE for objects of type @TYPE.
+ */
+#define GAIL_IMPLEMENT_FACTORY(GAIL_TYPE, TypeName, type_name, TYPE) \
+_GAIL_IMPLEMENT_FACTORY_BEGIN (GAIL_TYPE, TypeName, type_name) \
+_GAIL_IMPLEMENT_FACTORY_CREATE_ACCESSIBLE (GAIL_TYPE, TYPE) \
+_GAIL_IMPLEMENT_FACTORY_END (GAIL_TYPE, TypeName, type_name)
+
+/* Implements a AtkObjectFactory creating accessibles of type
+ * @GAIL_TYPE with creation func @create_accessible.
+ */
+#define GAIL_IMPLEMENT_FACTORY_WITH_FUNC(GAIL_TYPE, TypeName, type_name, create_accessible) \
+_GAIL_IMPLEMENT_FACTORY_BEGIN (GAIL_TYPE, TypeName, type_name) \
+{ return create_accessible (GTK_WIDGET (object)); } \
+_GAIL_IMPLEMENT_FACTORY_END (GAIL_TYPE, TypeName, type_name)
+
+#define GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY(GAIL_TYPE, TypeName, type_name, TYPE, create_accessible) \
+_GAIL_IMPLEMENT_FACTORY_BEGIN (GAIL_TYPE, TypeName, type_name) \
+{ \
+ g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object, TYPE), NULL);\
+ return create_accessible (); \
+} \
+_GAIL_IMPLEMENT_FACTORY_END (GAIL_TYPE, TypeName, type_name)
+
+#define GAIL_WIDGET_SET_FACTORY(widget_type, type_as_function) \
+ atk_registry_set_factory_type (atk_get_default_registry (), \
+ widget_type, \
+ type_as_function ## _factory_get_type ())
+
+#endif /* _GAIL_FACTORY_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailframe.h"
+
+static void gail_frame_class_init (GailFrameClass *klass);
+static void gail_frame_init (GailFrame *frame);
+static void gail_frame_initialize (AtkObject *accessible,
+ gpointer data);
+static const gchar* gail_frame_get_name (AtkObject *obj);
+
+G_DEFINE_TYPE (GailFrame, gail_frame, GAIL_TYPE_CONTAINER)
+
+static void
+gail_frame_class_init (GailFrameClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->initialize = gail_frame_initialize;
+ class->get_name = gail_frame_get_name;
+}
+
+static void
+gail_frame_init (GailFrame *frame)
+{
+}
+
+static void
+gail_frame_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_frame_parent_class)->initialize (accessible, data);
+
+ accessible->role = ATK_ROLE_PANEL;
+}
+
+static const gchar*
+gail_frame_get_name (AtkObject *obj)
+{
+ const gchar *name;
+ g_return_val_if_fail (GAIL_IS_FRAME (obj), NULL);
+
+ name = ATK_OBJECT_CLASS (gail_frame_parent_class)->get_name (obj);
+ if (name != NULL)
+ {
+ return name;
+ }
+ else
+ {
+ /*
+ * Get the text on the label
+ */
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ {
+ /*
+ * State is defunct
+ */
+ return NULL;
+ }
+ return gtk_frame_get_label (GTK_FRAME (widget));
+ }
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_FRAME_H__
+#define __GAIL_FRAME_H__
+
+#include "gailcontainer.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_FRAME (gail_frame_get_type ())
+#define GAIL_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_FRAME, GailFrame))
+#define GAIL_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_FRAME, GailFrameClass))
+#define GAIL_IS_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_FRAME))
+#define GAIL_IS_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_FRAME))
+#define GAIL_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_FRAME, GailFrameClass))
+
+typedef struct _GailFrame GailFrame;
+typedef struct _GailFrameClass GailFrameClass;
+
+struct _GailFrame
+{
+ GailContainer parent;
+};
+
+GType gail_frame_get_type (void);
+
+struct _GailFrameClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_FRAME_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailhtmlbox.h"
+#include "gailhtmlview.h"
+#include <libgtkhtml/layout/htmlbox.h>
+
+static void gail_html_box_class_init (GailHtmlBoxClass *klass);
+static void gail_html_box_initialize (AtkObject *obj,
+ gpointer data);
+static gint gail_html_box_get_index_in_parent (AtkObject *obj);
+static AtkStateSet* gail_html_box_ref_state_set (AtkObject *obj);
+
+static void gail_html_box_component_interface_init (AtkComponentIface *iface);
+static guint gail_html_box_add_focus_handler (AtkComponent *component,
+ AtkFocusHandler handler);
+static void gail_html_box_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+static gboolean gail_html_box_grab_focus (AtkComponent *component);
+static void gail_html_box_remove_focus_handler (AtkComponent *component,
+ guint handler_id);
+
+G_DEFINE_TYPE_WITH_CODE (GailHtmlBox, gail_html_box, ATK_TYPE_GOBJECT,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, gail_html_box_component_interface_init))
+
+static void
+gail_html_box_class_init (GailHtmlBoxClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->get_index_in_parent = gail_html_box_get_index_in_parent;
+ class->ref_state_set = gail_html_box_ref_state_set;
+ class->initialize = gail_html_box_initialize;
+}
+
+static void
+gail_html_box_initialize (AtkObject *obj,
+ gpointer data)
+{
+ HtmlBox *box;
+
+ ATK_OBJECT_CLASS (gail_html_box_parent_class)->initialize (obj, data);
+
+ obj->role = ATK_ROLE_UNKNOWN;
+
+ box = HTML_BOX (data);
+
+ /*
+ * We do not set the parent here for the root node of a HtmlView
+ */
+ if (box->parent)
+ {
+ atk_object_set_parent (obj,
+ atk_gobject_get_accessible (G_OBJECT (box->parent)));
+ }
+}
+
+static gint
+gail_html_box_get_index_in_parent (AtkObject *obj)
+{
+ AtkObject *parent;
+ AtkGObject *atk_gobj;
+ HtmlBox *box;
+ HtmlBox *parent_box;
+ gint n_children = 0;
+ GObject *g_obj;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX (obj), -1);
+
+ atk_gobj = ATK_GOBJECT (obj);
+ g_obj = atk_gobject_get_object (atk_gobj);
+ if (g_obj == NULL)
+ return -1;
+
+ g_return_val_if_fail (HTML_IS_BOX (g_obj), -1);
+ box = HTML_BOX (g_obj);
+ parent = atk_object_get_parent (obj);
+ if (GAIL_IS_HTML_VIEW (parent))
+ {
+ return 0;
+ }
+ else if (ATK_IS_GOBJECT (parent))
+ {
+ parent_box = HTML_BOX (atk_gobject_get_object (ATK_GOBJECT (parent)));
+ }
+ else
+ {
+ g_assert_not_reached ();
+ return -1;
+ }
+
+ if (parent_box)
+ {
+ HtmlBox *child;
+
+ child = parent_box->children;
+
+ while (child)
+ {
+ if (child == box)
+ return n_children;
+
+ n_children++;
+ child = child->next;
+ }
+ }
+ return -1;
+}
+
+static AtkStateSet*
+gail_html_box_ref_state_set (AtkObject *obj)
+{
+ AtkGObject *atk_gobj;
+ GObject *g_obj;
+ AtkStateSet *state_set;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX (obj), NULL);
+ atk_gobj = ATK_GOBJECT (obj);
+ state_set = ATK_OBJECT_CLASS (gail_html_box_parent_class)->ref_state_set (obj);
+
+ g_obj = atk_gobject_get_object (atk_gobj);
+ if (g_obj == NULL)
+ {
+ /* Object is defunct */
+ atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
+ }
+ else
+ {
+ HtmlBox *box;
+
+ box = HTML_BOX (g_obj);
+
+ if (HTML_BOX_GET_STYLE (box)->display != HTML_DISPLAY_NONE)
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+ }
+ }
+ return state_set;
+}
+
+static void
+gail_html_box_component_interface_init (AtkComponentIface *iface)
+{
+ /*
+ * Use default implementation for contains and get_position
+ */
+ iface->contains = NULL;
+ iface->get_position = NULL;
+ iface->add_focus_handler = gail_html_box_add_focus_handler;
+ iface->get_extents = gail_html_box_get_extents;
+ iface->get_size = NULL;
+ iface->grab_focus = gail_html_box_grab_focus;
+ iface->remove_focus_handler = gail_html_box_remove_focus_handler;
+ iface->set_extents = NULL;
+ iface->set_position = NULL;
+ iface->set_size = NULL;
+}
+
+static guint
+gail_html_box_add_focus_handler (AtkComponent *component,
+ AtkFocusHandler handler)
+{
+ return g_signal_connect_closure (component,
+ "focus-event",
+ g_cclosure_new (
+ G_CALLBACK (handler), NULL,
+ (GClosureNotify) NULL),
+ FALSE);
+}
+
+static void
+gail_html_box_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ AtkGObject *atk_gobj;
+ HtmlBox *box;
+ GObject *g_obj;
+
+ g_return_if_fail (GAIL_IS_HTML_BOX (component));
+
+ atk_gobj = ATK_GOBJECT (component);
+ g_obj = atk_gobject_get_object (atk_gobj);
+ if (g_obj == NULL)
+ return;
+
+ g_return_if_fail (HTML_IS_BOX (g_obj));
+ box = HTML_BOX (g_obj);
+
+ *x = html_box_get_absolute_x (box);
+ *y = html_box_get_absolute_y (box);
+ *width = box->width;
+ *height = box->height;
+
+ g_print ("%d %d %d %d\n",
+ html_box_get_absolute_x (box),
+ html_box_get_absolute_y (box),
+ html_box_get_containing_block_width (box),
+ html_box_get_containing_block_height (box));
+}
+
+static gboolean
+gail_html_box_grab_focus (AtkComponent *component)
+{
+ return TRUE;
+}
+
+static void
+gail_html_box_remove_focus_handler (AtkComponent *component,
+ guint handler_id)
+{
+ g_signal_handler_disconnect (ATK_OBJECT (component), handler_id);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_HTML_BOX_H__
+#define __GAIL_HTML_BOX_H__
+
+#include <atk/atk.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_HTML_BOX (gail_html_box_get_type ())
+#define GAIL_HTML_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_HTML_BOX, GailHtmlBox))
+#define GAIL_HTML_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_HTML_BOX, GailHtmlBoxClass))
+#define GAIL_IS_HTML_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_HTML_BOX))
+#define GAIL_IS_HTML_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_HTML_BOX))
+#define GAIL_HTML_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_HTML_BOX, GailHtmlBoxClass))
+
+typedef struct _GailHtmlBox GailHtmlBox;
+typedef struct _GailHtmlBoxClass GailHtmlBoxClass;
+
+struct _GailHtmlBox
+{
+ AtkGObject parent;
+};
+
+struct _GailHtmlBoxClass
+{
+ AtkGObjectClass parent_class;
+};
+
+GType gail_html_box_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GAIL_HTML_BOX_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <libgtkhtml/gtkhtml.h>
+#include "gailhtmlboxblock.h"
+
+static void gail_html_box_block_class_init (GailHtmlBoxBlockClass *klass);
+static gint gail_html_box_block_get_n_children (AtkObject *obj);
+static AtkObject* gail_html_box_block_ref_child (AtkObject *obj,
+ gint i);
+
+G_DEFINE_TYPE (GailHtmlBoxBlock, gail_html_box_block, GAIL_TYPE_HTML_BOX)
+
+AtkObject*
+gail_html_box_block_new (GObject *obj)
+{
+ GObject *object;
+ AtkObject *atk_object;
+
+ g_return_val_if_fail (HTML_IS_BOX_BLOCK (obj), NULL);
+ object = g_object_new (GAIL_TYPE_HTML_BOX_BLOCK, NULL);
+ atk_object = ATK_OBJECT (object);
+ atk_object_initialize (atk_object, obj);
+ atk_object->role = ATK_ROLE_PANEL;
+ return atk_object;
+}
+
+static void
+gail_html_box_block_class_init (GailHtmlBoxBlockClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->get_n_children = gail_html_box_block_get_n_children;
+ class->ref_child = gail_html_box_block_ref_child;
+}
+
+static gint
+gail_html_box_block_get_n_children (AtkObject *obj)
+{
+ AtkGObject *atk_gobject;
+ HtmlBox *box;
+ gint n_children = 0;
+ GObject *g_obj;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX_BLOCK (obj), 0);
+ atk_gobject = ATK_GOBJECT (obj);
+ g_obj = atk_gobject_get_object (atk_gobject);
+ if (g_obj == NULL)
+ return 0;
+
+ g_return_val_if_fail (HTML_IS_BOX (g_obj), 0);
+ box = HTML_BOX (g_obj);
+
+ if (box)
+ {
+ HtmlBox *child;
+
+ child = box->children;
+
+ while (child)
+ {
+ n_children++;
+ child = child->next;
+ }
+ }
+ return n_children;
+}
+
+static AtkObject *
+gail_html_box_block_ref_child (AtkObject *obj,
+ gint i)
+{
+ AtkGObject *atk_gobject;
+ GObject *g_obj;
+ HtmlBox *box;
+ AtkObject *atk_child = NULL;
+ gint n_children = 0;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX_BLOCK (obj), NULL);
+ atk_gobject = ATK_GOBJECT (obj);
+ g_obj = atk_gobject_get_object (atk_gobject);
+ if (g_obj == NULL)
+ return NULL;
+
+ g_return_val_if_fail (HTML_IS_BOX (g_obj), NULL);
+ box = HTML_BOX (g_obj);
+
+ if (box)
+ {
+ HtmlBox *child;
+
+ child = box->children;
+
+ while (child)
+ {
+ if (n_children == i)
+ {
+ atk_child = atk_gobject_get_accessible (G_OBJECT (child));
+ g_object_ref (atk_child);
+ break;
+ }
+ n_children++;
+ child = child->next;
+ }
+ }
+ return atk_child;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <libgtkhtml/gtkhtml.h>
+#include "gailhtmlboxembedded.h"
+
+static void gail_html_box_embedded_class_init (GailHtmlBoxEmbeddedClass *klass);
+static gint gail_html_box_embedded_get_n_children (AtkObject *obj);
+static AtkObject* gail_html_box_embedded_ref_child (AtkObject *obj,
+ gint i);
+
+G_DEFINE_TYPE (GailHtmlBoxEmbedded, gail_html_box_embedded, GAIL_TYPE_HTML_BOX)
+
+AtkObject*
+gail_html_box_embedded_new (GObject *obj)
+{
+ gpointer object;
+ AtkObject *atk_object;
+
+ g_return_val_if_fail (HTML_IS_BOX_EMBEDDED (obj), NULL);
+ object = g_object_new (GAIL_TYPE_HTML_BOX_EMBEDDED, NULL);
+ atk_object = ATK_OBJECT (object);
+ atk_object_initialize (atk_object, obj);
+ atk_object->role = ATK_ROLE_PANEL;
+ return atk_object;
+}
+
+static void
+gail_html_box_embedded_class_init (GailHtmlBoxEmbeddedClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->get_n_children = gail_html_box_embedded_get_n_children;
+ class->ref_child = gail_html_box_embedded_ref_child;
+}
+
+static gint
+gail_html_box_embedded_get_n_children (AtkObject *obj)
+{
+ AtkGObject *atk_gobject;
+ HtmlBoxEmbedded *box_embedded;
+ GObject *g_obj;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX_EMBEDDED (obj), 0);
+ atk_gobject = ATK_GOBJECT (obj);
+ g_obj = atk_gobject_get_object (atk_gobject);
+ if (g_obj == NULL)
+ /* State is defunct */
+ return 0;
+
+ g_return_val_if_fail (HTML_IS_BOX_EMBEDDED (g_obj), 0);
+
+ box_embedded = HTML_BOX_EMBEDDED (g_obj);
+ g_return_val_if_fail (box_embedded->widget, 0);
+ return 1;
+}
+
+static AtkObject*
+gail_html_box_embedded_ref_child (AtkObject *obj,
+ gint i)
+{
+ AtkGObject *atk_gobject;
+ HtmlBoxEmbedded *box_embedded;
+ GObject *g_obj;
+ AtkObject *atk_child;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX_EMBEDDED (obj), NULL);
+
+ if (i != 0)
+ return NULL;
+
+ atk_gobject = ATK_GOBJECT (obj);
+ g_obj = atk_gobject_get_object (atk_gobject);
+ if (g_obj == NULL)
+ /* State is defunct */
+ return NULL;
+
+ g_return_val_if_fail (HTML_IS_BOX_EMBEDDED (g_obj), NULL);
+
+ box_embedded = HTML_BOX_EMBEDDED (g_obj);
+ g_return_val_if_fail (box_embedded->widget, NULL);
+
+ atk_child = gtk_widget_get_accessible (box_embedded->widget);
+ g_object_ref (atk_child);
+ atk_object_set_parent (atk_child, obj);
+ return atk_child;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gailhtmlboxtext.h"
+
+static void gail_html_box_text_class_init (GailHtmlBoxTextClass *klass);
+static void gail_html_box_text_text_interface_init (AtkTextIface *iface);
+static gchar* gail_html_box_text_get_text (AtkText *text,
+ gint start_offset,
+ gint end_offset);
+static gchar* gail_html_box_text_get_text_after_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_html_box_text_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_html_box_text_get_text_before_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gunichar gail_html_box_text_get_character_at_offset
+ (AtkText *text,
+ gint offset);
+static gint gail_html_box_text_get_character_count (AtkText *text);
+static gint gail_html_box_text_get_caret_offset (AtkText *text);
+static gboolean gail_html_box_text_set_caret_offset (AtkText *text,
+ gint offset);
+static gint gail_html_box_text_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static void gail_html_box_text_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static AtkAttributeSet*
+ gail_html_box_text_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet*
+ gail_html_box_text_get_default_attributes (AtkText *text);
+static gint gail_html_box_text_get_n_selections (AtkText *text);
+static gchar* gail_html_box_text_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_pos,
+ gint *end_pos);
+static gboolean gail_html_box_text_add_selection (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gboolean gail_html_box_text_remove_selection (AtkText *text,
+ gint selection_num);
+static gboolean gail_html_box_text_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_pos,
+ gint end_pos);
+static AtkAttributeSet*
+ add_to_attr_set (AtkAttributeSet *attrib_set,
+ GtkTextAttributes *attrs,
+ AtkTextAttribute attr);
+static gchar* get_text_near_offset (AtkText *text,
+ GailOffsetType function,
+ AtkTextBoundary boundary_type,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+
+G_DEFINE_TYPE_WITH_CODE (GailHtmlBoxText, gail_html_box_text, GAIL_TYPE_HTML_BOX,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, gail_html_box_text_text_interface_init))
+
+AtkObject*
+gail_html_box_text_new (GObject *obj)
+{
+ gpointer object;
+ AtkObject *atk_object;
+ GailHtmlBoxText *gail_text;
+
+ g_return_val_if_fail (HTML_IS_BOX_TEXT (obj), NULL);
+ object = g_object_new (GAIL_TYPE_HTML_BOX_TEXT, NULL);
+ atk_object = ATK_OBJECT (object);
+ gail_text = GAIL_HTML_BOX_TEXT (object);
+
+ atk_object_initialize (atk_object, obj);
+ gail_text->texthelper = gail_text_helper_new ();
+#if 0
+ gail_text_helper_text_setup (gail_text->texthelper,
+ HTML_BOX_TEXT (obj)->master->text);
+#endif
+
+ atk_object->role = ATK_ROLE_TEXT;
+ return atk_object;
+}
+
+static void
+gail_html_box_text_class_init (GailHtmlBoxTextClass *klass)
+{
+}
+
+static void
+gail_html_box_text_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_html_box_text_get_text;
+ iface->get_text_after_offset = gail_html_box_text_get_text_after_offset;
+ iface->get_text_at_offset = gail_html_box_text_get_text_at_offset;
+ iface->get_text_before_offset = gail_html_box_text_get_text_before_offset;
+ iface->get_character_at_offset = gail_html_box_text_get_character_at_offset;
+ iface->get_character_count = gail_html_box_text_get_character_count;
+ iface->get_caret_offset = gail_html_box_text_get_caret_offset;
+ iface->set_caret_offset = gail_html_box_text_set_caret_offset;
+ iface->get_offset_at_point = gail_html_box_text_get_offset_at_point;
+ iface->get_character_extents = gail_html_box_text_get_character_extents;
+ iface->get_n_selections = gail_html_box_text_get_n_selections;
+ iface->get_selection = gail_html_box_text_get_selection;
+ iface->add_selection = gail_html_box_text_add_selection;
+ iface->remove_selection = gail_html_box_text_remove_selection;
+ iface->set_selection = gail_html_box_text_set_selection;
+ iface->get_run_attributes = gail_html_box_text_get_run_attributes;
+ iface->get_default_attributes = gail_html_box_text_get_default_attributes;
+}
+
+static gchar*
+gail_html_box_text_get_text (AtkText *text,
+ gint start_offset,
+ gint end_offset)
+{
+ GailHtmlBoxText *gail_text;
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), NULL);
+ gail_text = GAIL_HTML_BOX_TEXT (text);
+ g_return_val_if_fail (gail_text->texthelper, NULL);
+
+ buffer = gail_text->texthelper->buffer;
+ gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
+
+ return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+}
+
+static gchar*
+gail_html_box_text_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ return get_text_near_offset (text, GAIL_AFTER_OFFSET,
+ boundary_type, offset,
+ start_offset, end_offset);
+}
+
+static gchar*
+gail_html_box_text_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ return get_text_near_offset (text, GAIL_AT_OFFSET,
+ boundary_type, offset,
+ start_offset, end_offset);
+}
+
+static gchar*
+gail_html_box_text_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ return get_text_near_offset (text, GAIL_BEFORE_OFFSET,
+ boundary_type, offset,
+ start_offset, end_offset);
+}
+
+static gunichar
+gail_html_box_text_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GailHtmlBoxText *gail_item;
+ GtkTextIter start, end;
+ GtkTextBuffer *buffer;
+ gchar *string;
+ gchar *index;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), 0);
+ gail_item = GAIL_HTML_BOX_TEXT (text);
+ buffer = gail_item->texthelper->buffer;
+ gtk_text_buffer_get_start_iter (buffer, &start);
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ string = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+ index = g_utf8_offset_to_pointer (string, offset);
+ g_free (string);
+
+ return g_utf8_get_char (index);
+}
+
+static gint
+gail_html_box_text_get_character_count (AtkText *text)
+{
+ GtkTextBuffer *buffer;
+ GailHtmlBoxText *gail_text;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), 0);
+ gail_text = GAIL_HTML_BOX_TEXT (text);
+ g_return_val_if_fail (gail_text->texthelper, 0);
+ buffer = gail_text->texthelper->buffer;
+ return gtk_text_buffer_get_char_count (buffer);
+}
+
+static gint
+gail_html_box_text_get_caret_offset (AtkText *text)
+{
+ GailHtmlBoxText *gail_text;
+ GtkTextBuffer *buffer;
+ GtkTextMark *cursor_mark;
+ GtkTextIter cursor_itr;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), 0);
+ gail_text = GAIL_HTML_BOX_TEXT (text);
+ g_return_val_if_fail (gail_text->texthelper, 0);
+ buffer = gail_text->texthelper->buffer;
+ cursor_mark = gtk_text_buffer_get_insert (buffer);
+ gtk_text_buffer_get_iter_at_mark (buffer, &cursor_itr, cursor_mark);
+ return gtk_text_iter_get_offset (&cursor_itr);
+}
+
+static gboolean
+gail_html_box_text_set_caret_offset (AtkText *text,
+ gint offset)
+{
+ GailHtmlBoxText *gail_text;
+ GtkTextBuffer *buffer;
+ GtkTextIter pos_itr;
+
+ g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), FALSE);
+ gail_text = GAIL_HTML_BOX_TEXT (text);
+ g_return_val_if_fail (gail_text->texthelper, FALSE);
+ buffer = gail_text->texthelper->buffer;
+ gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, offset);
+ gtk_text_buffer_move_mark_by_name (buffer, "insert", &pos_itr);
+ return TRUE;
+}
+
+static gint
+gail_html_box_text_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ return -1;
+}
+
+static void
+gail_html_box_text_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ return;
+}
+
+static AtkAttributeSet*
+gail_html_box_text_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ return NULL;
+}
+
+static AtkAttributeSet*
+gail_html_box_text_get_default_attributes (AtkText *text)
+{
+ return NULL;
+}
+
+static gint
+gail_html_box_text_get_n_selections (AtkText *text)
+{
+ return 0;
+}
+
+static gchar*
+gail_html_box_text_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_pos,
+ gint *end_pos)
+{
+ return NULL;
+}
+
+static gboolean
+gail_html_box_text_add_selection (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ return FALSE;
+}
+
+static gboolean
+gail_html_box_text_remove_selection (AtkText *text,
+ gint selection_num)
+{
+ return FALSE;
+}
+
+static gboolean
+gail_html_box_text_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_pos,
+ gint end_pos)
+{
+ return FALSE;
+}
+
+static AtkAttributeSet*
+add_to_attr_set (AtkAttributeSet *attrib_set,
+ GtkTextAttributes *attrs,
+ AtkTextAttribute attr)
+{
+ gchar *value;
+
+ switch (attr)
+ {
+ case ATK_TEXT_ATTR_LEFT_MARGIN:
+ value = g_strdup_printf ("%i", attrs->left_margin);
+ break;
+ case ATK_TEXT_ATTR_RIGHT_MARGIN:
+ value = g_strdup_printf ("%i", attrs->right_margin);
+ break;
+ case ATK_TEXT_ATTR_INDENT:
+ value = g_strdup_printf ("%i", attrs->indent);
+ break;
+ case ATK_TEXT_ATTR_INVISIBLE:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->invisible));
+ break;
+ case ATK_TEXT_ATTR_EDITABLE:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->editable));
+ break;
+ case ATK_TEXT_ATTR_PIXELS_ABOVE_LINES:
+ value = g_strdup_printf ("%i", attrs->pixels_above_lines);
+ break;
+ case ATK_TEXT_ATTR_PIXELS_BELOW_LINES:
+ value = g_strdup_printf ("%i", attrs->pixels_below_lines);
+ break;
+ case ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP:
+ value = g_strdup_printf ("%i", attrs->pixels_inside_wrap);
+ break;
+ case ATK_TEXT_ATTR_BG_FULL_HEIGHT:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->bg_full_height));
+ break;
+ case ATK_TEXT_ATTR_RISE:
+ value = g_strdup_printf ("%i", attrs->appearance.rise);
+ break;
+ case ATK_TEXT_ATTR_UNDERLINE:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.underline));
+ break;
+ case ATK_TEXT_ATTR_STRIKETHROUGH:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.strikethrough));
+ break;
+ case ATK_TEXT_ATTR_SIZE:
+ value = g_strdup_printf ("%i",
+ pango_font_description_get_size (attrs->font));
+ break;
+ case ATK_TEXT_ATTR_SCALE:
+ value = g_strdup_printf ("%g", attrs->font_scale);
+ break;
+ case ATK_TEXT_ATTR_WEIGHT:
+ value = g_strdup_printf ("%d",
+ pango_font_description_get_weight (attrs->font));
+ break;
+ case ATK_TEXT_ATTR_LANGUAGE:
+ value = g_strdup ((gchar *)(attrs->language));
+ break;
+ case ATK_TEXT_ATTR_FAMILY_NAME:
+ value = g_strdup (pango_font_description_get_family (attrs->font));
+ break;
+ case ATK_TEXT_ATTR_BG_COLOR:
+ value = g_strdup_printf ("%u,%u,%u",
+ attrs->appearance.bg_color.red,
+ attrs->appearance.bg_color.green,
+ attrs->appearance.bg_color.blue);
+ break;
+ case ATK_TEXT_ATTR_FG_COLOR:
+ value = g_strdup_printf ("%u,%u,%u",
+ attrs->appearance.fg_color.red,
+ attrs->appearance.fg_color.green,
+ attrs->appearance.fg_color.blue);
+ break;
+ case ATK_TEXT_ATTR_BG_STIPPLE:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.bg_stipple ? 1 : 0));
+ break;
+ case ATK_TEXT_ATTR_FG_STIPPLE:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.fg_stipple ? 1 : 0));
+ break;
+ case ATK_TEXT_ATTR_WRAP_MODE:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->wrap_mode));
+ break;
+ case ATK_TEXT_ATTR_DIRECTION:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->direction));
+ break;
+ case ATK_TEXT_ATTR_JUSTIFICATION:
+ value = g_strdup (atk_text_attribute_get_value (attr, attrs->justification));
+ break;
+ case ATK_TEXT_ATTR_STRETCH:
+ value = g_strdup (atk_text_attribute_get_value (attr,
+ pango_font_description_get_stretch (attrs->font)));
+ break;
+ case ATK_TEXT_ATTR_VARIANT:
+ value = g_strdup (atk_text_attribute_get_value (attr,
+ pango_font_description_get_variant (attrs->font)));
+ break;
+ case ATK_TEXT_ATTR_STYLE:
+ value = g_strdup (atk_text_attribute_get_value (attr,
+ pango_font_description_get_style (attrs->font)));
+ break;
+ default:
+ value = NULL;
+ break;
+ }
+ return gail_text_helper_add_attribute (attrib_set,
+ attr,
+ value);
+}
+
+static gchar*
+get_text_near_offset (AtkText *text,
+ GailOffsetType function,
+ AtkTextBoundary boundary_type,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ return gail_text_helper_get_text (GAIL_HTML_BOX_TEXT (text)->texthelper, NULL,
+ function, boundary_type, offset,
+ start_offset, end_offset);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailimage.h"
+
+static void gail_image_class_init (GailImageClass *klass);
+static void gail_image_init (GailImage *image);
+static void gail_image_initialize (AtkObject *accessible,
+ gpointer data);
+static const gchar* gail_image_get_name (AtkObject *accessible);
+
+
+static void atk_image_interface_init (AtkImageIface *iface);
+
+static const gchar *
+ gail_image_get_image_description (AtkImage *image);
+static void gail_image_get_image_position (AtkImage *image,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type);
+static void gail_image_get_image_size (AtkImage *image,
+ gint *width,
+ gint *height);
+static gboolean gail_image_set_image_description (AtkImage *image,
+ const gchar *description);
+static void gail_image_finalize (GObject *object);
+
+G_DEFINE_TYPE_WITH_CODE (GailImage, gail_image, GAIL_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init))
+
+static void
+gail_image_class_init (GailImageClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = gail_image_finalize;
+ class->initialize = gail_image_initialize;
+ class->get_name = gail_image_get_name;
+}
+
+static void
+gail_image_init (GailImage *image)
+{
+ image->image_description = NULL;
+}
+
+static void
+gail_image_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_image_parent_class)->initialize (accessible, data);
+
+ accessible->role = ATK_ROLE_ICON;
+}
+
+/* Copied from gtktoolbar.c, keep in sync */
+static gchar *
+elide_underscores (const gchar *original)
+{
+ gchar *q, *result;
+ const gchar *p, *end;
+ gsize len;
+ gboolean last_underscore;
+
+ if (!original)
+ return NULL;
+
+ len = strlen (original);
+ q = result = g_malloc (len + 1);
+ last_underscore = FALSE;
+
+ end = original + len;
+ for (p = original; p < end; p++)
+ {
+ if (!last_underscore && *p == '_')
+ last_underscore = TRUE;
+ else
+ {
+ last_underscore = FALSE;
+ if (original + 2 <= p && p + 1 <= end &&
+ p[-2] == '(' && p[-1] == '_' && p[0] != '_' && p[1] == ')')
+ {
+ q--;
+ *q = '\0';
+ p++;
+ }
+ else
+ *q++ = *p;
+ }
+ }
+
+ if (last_underscore)
+ *q++ = '_';
+
+ *q = '\0';
+
+ return result;
+}
+
+static const gchar*
+gail_image_get_name (AtkObject *accessible)
+{
+ GtkWidget* widget;
+ GtkImage *image;
+ GailImage *image_accessible;
+ GtkStockItem stock_item;
+ gchar *stock_id;
+ const gchar *name;
+
+ name = ATK_OBJECT_CLASS (gail_image_parent_class)->get_name (accessible);
+ if (name)
+ return name;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ /*
+ * State is defunct
+ */
+ if (widget == NULL)
+ return NULL;
+
+ g_return_val_if_fail (GTK_IS_IMAGE (widget), NULL);
+ image = GTK_IMAGE (widget);
+ image_accessible = GAIL_IMAGE (accessible);
+
+ g_free (image_accessible->stock_name);
+ image_accessible->stock_name = NULL;
+
+ if (gtk_image_get_storage_type (image) != GTK_IMAGE_STOCK)
+ return NULL;
+
+ gtk_image_get_stock (image, &stock_id, NULL);
+ if (stock_id == NULL)
+ return NULL;
+
+ if (!gtk_stock_lookup (stock_id, &stock_item))
+ return NULL;
+
+ image_accessible->stock_name = elide_underscores (stock_item.label);
+ return image_accessible->stock_name;
+}
+
+static void
+atk_image_interface_init (AtkImageIface *iface)
+{
+ iface->get_image_description = gail_image_get_image_description;
+ iface->get_image_position = gail_image_get_image_position;
+ iface->get_image_size = gail_image_get_image_size;
+ iface->set_image_description = gail_image_set_image_description;
+}
+
+static const gchar *
+gail_image_get_image_description (AtkImage *image)
+{
+ GailImage* aimage = GAIL_IMAGE (image);
+
+ return aimage->image_description;
+}
+
+static void
+gail_image_get_image_position (AtkImage *image,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type)
+{
+ atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
+}
+
+static void
+gail_image_get_image_size (AtkImage *image,
+ gint *width,
+ gint *height)
+{
+ GtkWidget* widget;
+ GtkImage *gtk_image;
+ GtkImageType image_type;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
+ if (widget == 0)
+ {
+ /* State is defunct */
+ *height = -1;
+ *width = -1;
+ return;
+ }
+
+ gtk_image = GTK_IMAGE(widget);
+
+ image_type = gtk_image_get_storage_type(gtk_image);
+
+ switch(image_type) {
+ case GTK_IMAGE_PIXBUF:
+ {
+ GdkPixbuf *pixbuf;
+ pixbuf = gtk_image_get_pixbuf(gtk_image);
+ *height = gdk_pixbuf_get_height(pixbuf);
+ *width = gdk_pixbuf_get_width(pixbuf);
+ break;
+ }
+ case GTK_IMAGE_STOCK:
+ case GTK_IMAGE_ICON_SET:
+ case GTK_IMAGE_ICON_NAME:
+ case GTK_IMAGE_GICON:
+ {
+ GtkIconSize size;
+ GtkSettings *settings;
+
+ settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
+
+ g_object_get (gtk_image, "icon-size", &size, NULL);
+ gtk_icon_size_lookup_for_settings (settings, size, width, height);
+ break;
+ }
+ case GTK_IMAGE_ANIMATION:
+ {
+ GdkPixbufAnimation *animation;
+ animation = gtk_image_get_animation(gtk_image);
+ *height = gdk_pixbuf_animation_get_height(animation);
+ *width = gdk_pixbuf_animation_get_width(animation);
+ break;
+ }
+ default:
+ {
+ *height = -1;
+ *width = -1;
+ break;
+ }
+ }
+}
+
+static gboolean
+gail_image_set_image_description (AtkImage *image,
+ const gchar *description)
+{
+ GailImage* aimage = GAIL_IMAGE (image);
+
+ g_free (aimage->image_description);
+ aimage->image_description = g_strdup (description);
+ return TRUE;
+}
+
+static void
+gail_image_finalize (GObject *object)
+{
+ GailImage *aimage = GAIL_IMAGE (object);
+
+ g_free (aimage->image_description);
+ g_free (aimage->stock_name);
+
+ G_OBJECT_CLASS (gail_image_parent_class)->finalize (object);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_IMAGE_H__
+#define __GAIL_IMAGE_H__
+
+#include "gailwidget.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_IMAGE (gail_image_get_type ())
+#define GAIL_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_IMAGE, GailImage))
+#define GAIL_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_IMAGE, GailImageClass))
+#define GAIL_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_IMAGE))
+#define GAIL_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_IMAGE))
+#define GAIL_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_IMAGE, GailImageClass))
+
+typedef struct _GailImage GailImage;
+typedef struct _GailImageClass GailImageClass;
+
+struct _GailImage
+{
+ GailWidget parent;
+
+ gchar* image_description;
+ gchar* stock_name;
+};
+
+GType gail_image_get_type (void);
+
+struct _GailImageClass
+{
+ GailWidgetClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_IMAGE_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailimagecell.h"
+
+static void gail_image_cell_class_init (GailImageCellClass *klass);
+static void gail_image_cell_init (GailImageCell *image_cell);
+
+static void gail_image_cell_finalize (GObject *object);
+
+/* AtkImage */
+static void atk_image_interface_init (AtkImageIface *iface);
+static const gchar *
+ gail_image_cell_get_image_description (AtkImage *image);
+static gboolean gail_image_cell_set_image_description (AtkImage *image,
+ const gchar *description);
+static void gail_image_cell_get_image_position (AtkImage *image,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type);
+static void gail_image_cell_get_image_size (AtkImage *image,
+ gint *width,
+ gint *height);
+
+/* Misc */
+
+static gboolean gail_image_cell_update_cache (GailRendererCell *cell,
+ gboolean emit_change_signal);
+
+// FIXMEchpe static!!!
+gchar *gail_image_cell_property_list[] = {
+ "pixbuf",
+ NULL
+};
+
+G_DEFINE_TYPE_WITH_CODE (GailImageCell, gail_image_cell, GAIL_TYPE_RENDERER_CELL,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init))
+
+static void
+gail_image_cell_class_init (GailImageCellClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GailRendererCellClass *renderer_cell_class = GAIL_RENDERER_CELL_CLASS(klass);
+
+ gobject_class->finalize = gail_image_cell_finalize;
+
+ renderer_cell_class->update_cache = gail_image_cell_update_cache;
+ renderer_cell_class->property_list = gail_image_cell_property_list;
+}
+
+AtkObject*
+gail_image_cell_new (void)
+{
+ GObject *object;
+ AtkObject *atk_object;
+ GailRendererCell *cell;
+
+ object = g_object_new (GAIL_TYPE_IMAGE_CELL, NULL);
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ atk_object = ATK_OBJECT (object);
+ atk_object->role = ATK_ROLE_TABLE_CELL;
+
+ cell = GAIL_RENDERER_CELL(object);
+
+ cell->renderer = gtk_cell_renderer_pixbuf_new ();
+ g_object_ref_sink (cell->renderer);
+ return atk_object;
+}
+
+static void
+gail_image_cell_init (GailImageCell *image_cell)
+{
+ image_cell->image_description = NULL;
+}
+
+
+static void
+gail_image_cell_finalize (GObject *object)
+{
+ GailImageCell *image_cell = GAIL_IMAGE_CELL (object);
+
+ g_free (image_cell->image_description);
+ G_OBJECT_CLASS (gail_image_cell_parent_class)->finalize (object);
+}
+
+static gboolean
+gail_image_cell_update_cache (GailRendererCell *cell,
+ gboolean emit_change_signal)
+{
+ return FALSE;
+}
+
+static void
+atk_image_interface_init (AtkImageIface *iface)
+{
+ iface->get_image_description = gail_image_cell_get_image_description;
+ iface->set_image_description = gail_image_cell_set_image_description;
+ iface->get_image_position = gail_image_cell_get_image_position;
+ iface->get_image_size = gail_image_cell_get_image_size;
+}
+
+static const gchar *
+gail_image_cell_get_image_description (AtkImage *image)
+{
+ GailImageCell *image_cell;
+
+ image_cell = GAIL_IMAGE_CELL (image);
+ return image_cell->image_description;
+}
+
+static gboolean
+gail_image_cell_set_image_description (AtkImage *image,
+ const gchar *description)
+{
+ GailImageCell *image_cell;
+
+ image_cell = GAIL_IMAGE_CELL (image);
+ g_free (image_cell->image_description);
+ image_cell->image_description = g_strdup (description);
+ if (image_cell->image_description)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void
+gail_image_cell_get_image_position (AtkImage *image,
+ gint *x,
+ gint *y,
+ AtkCoordType coord_type)
+{
+ atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
+}
+
+static void
+gail_image_cell_get_image_size (AtkImage *image,
+ gint *width,
+ gint *height)
+{
+ GailImageCell *cell = GAIL_IMAGE_CELL (image);
+ GtkCellRenderer *cell_renderer;
+ GdkPixbuf *pixbuf;
+
+ cell_renderer = GAIL_RENDERER_CELL (cell)->renderer;
+ g_object_get (GTK_CELL_RENDERER_PIXBUF (cell_renderer), "pixbuf", &pixbuf, NULL);
+
+ *width = gdk_pixbuf_get_width (pixbuf);
+ *height = gdk_pixbuf_get_height (pixbuf);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_IMAGE_CELL_H__
+#define __GAIL_IMAGE_CELL_H__
+
+#include <atk/atk.h>
+#include "gailrenderercell.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_IMAGE_CELL (gail_image_cell_get_type ())
+#define GAIL_IMAGE_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_IMAGE_CELL, GailImageCell))
+#define GAIL_IMAGE_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_IMAGE_CELL, GailImageCellClass))
+#define GAIL_IS_IMAGE_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_IMAGE_CELL))
+#define GAIL_IS_IMAGE_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_IMAGE_CELL))78
+#define GAIL_IMAGE_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_IMAGE_CELL, GailImageCellClass))
+
+typedef struct _GailImageCell GailImageCell;
+typedef struct _GailImageCellClass GailImageCellClass;
+
+struct _GailImageCell
+{
+ GailRendererCell parent;
+
+ gchar *image_description;
+ gint x, y;
+};
+
+GType gail_image_cell_get_type (void);
+
+struct _GailImageCellClass
+{
+ GailRendererCellClass parent_class;
+};
+
+AtkObject *gail_image_cell_new (void);
+
+G_END_DECLS
+
+#endif /* __GAIL_TREE_VIEW_IMAGE_CELL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include "gaillabel.h"
+#include "gailwindow.h"
+#include <libgail-util/gailmisc.h>
+
+static void gail_label_class_init (GailLabelClass *klass);
+static void gail_label_init (GailLabel *label);
+static void gail_label_real_initialize (AtkObject *obj,
+ gpointer data);
+static void gail_label_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+static void gail_label_map_gtk (GtkWidget *widget,
+ gpointer data);
+static void gail_label_init_text_util (GailLabel *gail_label,
+ GtkWidget *widget);
+static void gail_label_finalize (GObject *object);
+
+static void atk_text_interface_init (AtkTextIface *iface);
+
+/* atkobject.h */
+
+static const gchar* gail_label_get_name (AtkObject *accessible);
+static AtkStateSet* gail_label_ref_state_set (AtkObject *accessible);
+static AtkRelationSet* gail_label_ref_relation_set (AtkObject *accessible);
+
+/* atktext.h */
+
+static gchar* gail_label_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gunichar gail_label_get_character_at_offset(AtkText *text,
+ gint offset);
+static gchar* gail_label_get_text_before_offset(AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_label_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_label_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gint gail_label_get_character_count (AtkText *text);
+static gint gail_label_get_caret_offset (AtkText *text);
+static gboolean gail_label_set_caret_offset (AtkText *text,
+ gint offset);
+static gint gail_label_get_n_selections (AtkText *text);
+static gchar* gail_label_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_offset,
+ gint *end_offset);
+static gboolean gail_label_add_selection (AtkText *text,
+ gint start_offset,
+ gint end_offset);
+static gboolean gail_label_remove_selection (AtkText *text,
+ gint selection_num);
+static gboolean gail_label_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_offset,
+ gint end_offset);
+static void gail_label_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static gint gail_label_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static AtkAttributeSet* gail_label_get_run_attributes
+ (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet* gail_label_get_default_attributes
+ (AtkText *text);
+
+G_DEFINE_TYPE_WITH_CODE (GailLabel, gail_label, GAIL_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
+
+static void
+gail_label_class_init (GailLabelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailWidgetClass *widget_class;
+
+ gobject_class->finalize = gail_label_finalize;
+
+ widget_class = (GailWidgetClass*)klass;
+ widget_class->notify_gtk = gail_label_real_notify_gtk;
+
+ class->get_name = gail_label_get_name;
+ class->ref_state_set = gail_label_ref_state_set;
+ class->ref_relation_set = gail_label_ref_relation_set;
+ class->initialize = gail_label_real_initialize;
+}
+
+static void
+gail_label_init (GailLabel *label)
+{
+}
+
+static void
+gail_label_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkWidget *widget;
+ GailLabel *gail_label;
+
+ ATK_OBJECT_CLASS (gail_label_parent_class)->initialize (obj, data);
+
+ gail_label = GAIL_LABEL (obj);
+
+ gail_label->window_create_handler = 0;
+ gail_label->has_top_level = FALSE;
+ gail_label->cursor_position = 0;
+ gail_label->selection_bound = 0;
+ gail_label->textutil = NULL;
+ gail_label->label_length = 0;
+
+ widget = GTK_WIDGET (data);
+
+ if (gtk_widget_get_mapped (widget))
+ gail_label_init_text_util (gail_label, widget);
+ else
+ g_signal_connect (widget,
+ "map",
+ G_CALLBACK (gail_label_map_gtk),
+ gail_label);
+
+ /*
+ * Check whether ancestor of GtkLabel is a GtkButton and if so
+ * set accessible parent for GailLabel
+ */
+ while (widget != NULL)
+ {
+ widget = gtk_widget_get_parent (widget);
+ if (GTK_IS_BUTTON (widget))
+ {
+ atk_object_set_parent (obj, gtk_widget_get_accessible (widget));
+ break;
+ }
+ }
+
+ if (GTK_IS_ACCEL_LABEL (widget))
+ obj->role = ATK_ROLE_ACCEL_LABEL;
+ else
+ obj->role = ATK_ROLE_LABEL;
+}
+
+static void
+gail_label_map_gtk (GtkWidget *widget,
+ gpointer data)
+{
+ GailLabel *gail_label;
+
+ gail_label = GAIL_LABEL (data);
+ gail_label_init_text_util (gail_label, widget);
+}
+
+static void
+gail_label_init_text_util (GailLabel *gail_label,
+ GtkWidget *widget)
+{
+ GtkLabel *label;
+ const gchar *label_text;
+
+ if (gail_label->textutil == NULL)
+ gail_label->textutil = gail_text_util_new ();
+
+ label = GTK_LABEL (widget);
+ label_text = gtk_label_get_text (label);
+ gail_text_util_text_setup (gail_label->textutil, label_text);
+
+ if (label_text == NULL)
+ gail_label->label_length = 0;
+ else
+ gail_label->label_length = g_utf8_strlen (label_text, -1);
+}
+
+static void
+notify_name_change (AtkObject *atk_obj)
+{
+ GtkLabel *label;
+ GailLabel *gail_label;
+ GtkWidget *widget;
+ GObject *gail_obj;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return;
+
+ gail_obj = G_OBJECT (atk_obj);
+ label = GTK_LABEL (widget);
+ gail_label = GAIL_LABEL (atk_obj);
+
+ if (gail_label->textutil == NULL)
+ return;
+
+ /*
+ * Check whether the label has actually changed before emitting
+ * notification.
+ */
+ if (gail_label->textutil->buffer)
+ {
+ GtkTextIter start, end;
+ const char *new_label;
+ char *old_label;
+ int same;
+
+ gtk_text_buffer_get_start_iter (gail_label->textutil->buffer, &start);
+ gtk_text_buffer_get_end_iter (gail_label->textutil->buffer, &end);
+ old_label = gtk_text_buffer_get_text (gail_label->textutil->buffer, &start, &end, FALSE);
+ new_label = gtk_label_get_text (label);
+ same = strcmp (new_label, old_label);
+ g_free (old_label);
+ if (same == 0)
+ return;
+ }
+
+ /* Create a delete text and an insert text signal */
+
+ g_signal_emit_by_name (gail_obj, "text_changed::delete", 0,
+ gail_label->label_length);
+
+ gail_label_init_text_util (gail_label, widget);
+
+ g_signal_emit_by_name (gail_obj, "text_changed::insert", 0,
+ gail_label->label_length);
+
+ if (atk_obj->name == NULL)
+ /*
+ * The label has changed so notify a change in accessible-name
+ */
+ g_object_notify (gail_obj, "accessible-name");
+
+ g_signal_emit_by_name (gail_obj, "visible_data_changed");
+}
+
+static void
+window_created (GObject *obj,
+ gpointer data)
+{
+ g_return_if_fail (GAIL_LABEL (data));
+
+ notify_name_change (ATK_OBJECT (data));
+}
+
+static void
+gail_label_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkWidget *widget = GTK_WIDGET (obj);
+ AtkObject* atk_obj = gtk_widget_get_accessible (widget);
+ GtkLabel *label;
+ GailLabel *gail_label;
+ GObject *gail_obj;
+ AtkObject *top_level;
+ AtkObject *temp_obj;
+
+ gail_label = GAIL_LABEL (atk_obj);
+
+ if (strcmp (pspec->name, "label") == 0)
+ {
+ /*
+ * We may get a label change for a label which is not attached to an
+ * application. We wait until the toplevel window is created before
+ * emitting the notification.
+ *
+ * This happens when [Ctrl+]Alt+Tab is pressed in metacity
+ */
+ if (!gail_label->has_top_level)
+ {
+ temp_obj = atk_obj;
+ top_level = NULL;
+ while (temp_obj)
+ {
+ top_level = temp_obj;
+ temp_obj = atk_object_get_parent (top_level);
+ }
+ if (atk_object_get_role (top_level) != ATK_ROLE_APPLICATION)
+ {
+ if (gail_label->window_create_handler == 0 &&
+ GAIL_IS_WINDOW (top_level))
+ gail_label->window_create_handler = g_signal_connect_after (top_level, "create", G_CALLBACK (window_created), atk_obj);
+ }
+ else
+ gail_label->has_top_level = TRUE;
+ }
+ if (gail_label->has_top_level)
+ notify_name_change (atk_obj);
+ }
+ else if (strcmp (pspec->name, "cursor-position") == 0)
+ {
+ gint start, end, tmp;
+ gboolean text_caret_moved = FALSE;
+ gboolean selection_changed = FALSE;
+
+ gail_obj = G_OBJECT (atk_obj);
+ label = GTK_LABEL (widget);
+
+ if (gail_label->selection_bound != -1 && gail_label->selection_bound < gail_label->cursor_position)
+ {
+ tmp = gail_label->selection_bound;
+ gail_label->selection_bound = gail_label->cursor_position;
+ gail_label->cursor_position = tmp;
+ }
+
+ if (gtk_label_get_selection_bounds (label, &start, &end))
+ {
+ if (start != gail_label->cursor_position ||
+ end != gail_label->selection_bound)
+ {
+ if (end != gail_label->selection_bound)
+ {
+ gail_label->selection_bound = start;
+ gail_label->cursor_position = end;
+ }
+ else
+ {
+ gail_label->selection_bound = end;
+ gail_label->cursor_position = start;
+ }
+ text_caret_moved = TRUE;
+ if (start != end)
+ selection_changed = TRUE;
+ }
+ }
+ else
+ {
+ if (gail_label->cursor_position != gail_label->selection_bound)
+ selection_changed = TRUE;
+ if (gtk_label_get_selectable (label))
+ {
+ if (gail_label->cursor_position != -1 && start != gail_label->cursor_position)
+ text_caret_moved = TRUE;
+ if (gail_label->selection_bound != -1 && end != gail_label->selection_bound)
+ {
+ text_caret_moved = TRUE;
+ gail_label->cursor_position = end;
+ gail_label->selection_bound = start;
+ }
+ else
+ {
+ gail_label->cursor_position = start;
+ gail_label->selection_bound = end;
+ }
+ }
+ else
+ {
+ /* GtkLabel has become non selectable */
+
+ gail_label->cursor_position = 0;
+ gail_label->selection_bound = 0;
+ text_caret_moved = TRUE;
+ }
+
+ }
+ if (text_caret_moved)
+ g_signal_emit_by_name (gail_obj, "text_caret_moved",
+ gail_label->cursor_position);
+ if (selection_changed)
+ g_signal_emit_by_name (gail_obj, "text_selection_changed");
+
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_label_parent_class)->notify_gtk (obj, pspec);
+}
+
+static void
+gail_label_finalize (GObject *object)
+{
+ GailLabel *label = GAIL_LABEL (object);
+
+ if (label->textutil)
+ g_object_unref (label->textutil);
+ G_OBJECT_CLASS (gail_label_parent_class)->finalize (object);
+}
+
+
+/* atkobject.h */
+
+static AtkStateSet*
+gail_label_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GtkWidget *widget;
+
+ state_set = ATK_OBJECT_CLASS (gail_label_parent_class)->ref_state_set (accessible);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ return state_set;
+
+ atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
+
+ return state_set;
+}
+
+AtkRelationSet*
+gail_label_ref_relation_set (AtkObject *obj)
+{
+ GtkWidget *widget;
+ AtkRelationSet *relation_set;
+
+ g_return_val_if_fail (GAIL_IS_LABEL (obj), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ relation_set = ATK_OBJECT_CLASS (gail_label_parent_class)->ref_relation_set (obj);
+
+ if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABEL_FOR))
+ {
+ /*
+ * Get the mnemonic widget
+ *
+ * The relation set is not updated if the mnemonic widget is changed
+ */
+ GtkWidget *mnemonic_widget = gtk_label_get_mnemonic_widget (GTK_LABEL (widget));
+
+ if (mnemonic_widget)
+ {
+ AtkObject *accessible_array[1];
+ AtkRelation* relation;
+
+ if (!gtk_widget_get_can_focus (mnemonic_widget))
+ {
+ /*
+ * Handle the case where a GtkFileChooserButton is specified as the
+ * mnemonic widget. use the combobox which is a child of the
+ * GtkFileChooserButton as the mnemonic widget. See bug #359843.
+ */
+ if (GTK_IS_BOX (mnemonic_widget))
+ {
+ GList *list, *tmpl;
+
+ list = gtk_container_get_children (GTK_CONTAINER (mnemonic_widget));
+ if (g_list_length (list) == 2)
+ {
+ tmpl = g_list_last (list);
+ if (GTK_IS_COMBO_BOX(tmpl->data))
+ {
+ mnemonic_widget = GTK_WIDGET(tmpl->data);
+ }
+ }
+ g_list_free (list);
+ }
+ }
+ accessible_array[0] = gtk_widget_get_accessible (mnemonic_widget);
+ relation = atk_relation_new (accessible_array, 1,
+ ATK_RELATION_LABEL_FOR);
+ atk_relation_set_add (relation_set, relation);
+ /*
+ * Unref the relation so that it is not leaked.
+ */
+ g_object_unref (relation);
+ }
+ }
+ return relation_set;
+}
+
+static const gchar*
+gail_label_get_name (AtkObject *accessible)
+{
+ const gchar *name;
+
+ g_return_val_if_fail (GAIL_IS_LABEL (accessible), NULL);
+
+ name = ATK_OBJECT_CLASS (gail_label_parent_class)->get_name (accessible);
+ if (name != NULL)
+ return name;
+ else
+ {
+ /*
+ * Get the text on the label
+ */
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ g_return_val_if_fail (GTK_IS_LABEL (widget), NULL);
+
+ return gtk_label_get_text (GTK_LABEL (widget));
+ }
+}
+
+/* atktext.h */
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_label_get_text;
+ iface->get_character_at_offset = gail_label_get_character_at_offset;
+ iface->get_text_before_offset = gail_label_get_text_before_offset;
+ iface->get_text_at_offset = gail_label_get_text_at_offset;
+ iface->get_text_after_offset = gail_label_get_text_after_offset;
+ iface->get_character_count = gail_label_get_character_count;
+ iface->get_caret_offset = gail_label_get_caret_offset;
+ iface->set_caret_offset = gail_label_set_caret_offset;
+ iface->get_n_selections = gail_label_get_n_selections;
+ iface->get_selection = gail_label_get_selection;
+ iface->add_selection = gail_label_add_selection;
+ iface->remove_selection = gail_label_remove_selection;
+ iface->set_selection = gail_label_set_selection;
+ iface->get_character_extents = gail_label_get_character_extents;
+ iface->get_offset_at_point = gail_label_get_offset_at_point;
+ iface->get_run_attributes = gail_label_get_run_attributes;
+ iface->get_default_attributes = gail_label_get_default_attributes;
+}
+
+static gchar*
+gail_label_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = GTK_LABEL (widget);
+
+ label_text = gtk_label_get_text (label);
+
+ if (label_text == NULL)
+ return NULL;
+ else
+ {
+ if (GAIL_LABEL (text)->textutil == NULL)
+ gail_label_init_text_util (GAIL_LABEL (text), widget);
+ return gail_text_util_get_substring (GAIL_LABEL(text)->textutil,
+ start_pos, end_pos);
+ }
+}
+
+static gchar*
+gail_label_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get label */
+ label = GTK_LABEL (widget);
+
+ return gail_text_util_get_text (GAIL_LABEL (text)->textutil,
+ gtk_label_get_layout (label), GAIL_BEFORE_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_label_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get label */
+ label = GTK_LABEL (widget);
+
+ return gail_text_util_get_text (GAIL_LABEL (text)->textutil,
+ gtk_label_get_layout (label), GAIL_AT_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_label_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return NULL;
+ }
+
+ /* Get label */
+ label = GTK_LABEL (widget);
+
+ return gail_text_util_get_text (GAIL_LABEL (text)->textutil,
+ gtk_label_get_layout (label), GAIL_AFTER_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gint
+gail_label_get_character_count (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ label = GTK_LABEL (widget);
+ return g_utf8_strlen (gtk_label_get_text (label), -1);
+}
+
+static gint
+gail_label_get_caret_offset (AtkText *text)
+{
+ return GAIL_LABEL (text)->cursor_position;
+}
+
+static gboolean
+gail_label_set_caret_offset (AtkText *text,
+ gint offset)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ label = GTK_LABEL (widget);
+
+ if (gtk_label_get_selectable (label) &&
+ offset >= 0 &&
+ offset <= g_utf8_strlen (gtk_label_get_text (label), -1))
+ {
+ gtk_label_select_region (label, offset, offset);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gint
+gail_label_get_n_selections (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+ gint start, end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ label = GTK_LABEL (widget);
+
+ if (!gtk_label_get_selectable (label))
+ return 0;
+
+ if (gtk_label_get_selection_bounds (label, &start, &end))
+ return 1;
+ else
+ return 0;
+}
+
+static gchar*
+gail_label_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_pos,
+ gint *end_pos)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = GTK_LABEL (widget);
+
+ /* Only let the user get the selection if one is set, and if the
+ * selection_num is 0.
+ */
+ if (!gtk_label_get_selectable( label) || selection_num != 0)
+ return NULL;
+
+ if (gtk_label_get_selection_bounds (label, start_pos, end_pos))
+ {
+ const gchar* label_text = gtk_label_get_text (label);
+
+ if (label_text == NULL)
+ return 0;
+ else
+ return gail_text_util_get_substring (GAIL_LABEL (text)->textutil,
+ *start_pos, *end_pos);
+ }
+ else
+ return NULL;
+}
+
+static gboolean
+gail_label_add_selection (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+ gint start, end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ label = GTK_LABEL (widget);
+
+ if (!gtk_label_get_selectable (label))
+ return FALSE;
+
+ if (! gtk_label_get_selection_bounds (label, &start, &end))
+ {
+ gtk_label_select_region (label, start_pos, end_pos);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+gail_label_remove_selection (AtkText *text,
+ gint selection_num)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+ gint start, end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ if (selection_num != 0)
+ return FALSE;
+
+ label = GTK_LABEL (widget);
+
+ if (!gtk_label_get_selectable (label))
+ return FALSE;
+
+ if (gtk_label_get_selection_bounds (label, &start, &end))
+ {
+ gtk_label_select_region (label, 0, 0);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+gail_label_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+ gint start, end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ if (selection_num != 0)
+ return FALSE;
+
+ label = GTK_LABEL (widget);
+
+ if (!gtk_label_get_selectable (label))
+ return FALSE;
+
+ if (gtk_label_get_selection_bounds (label, &start, &end))
+ {
+ gtk_label_select_region (label, start_pos, end_pos);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+gail_label_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+ PangoRectangle char_rect;
+ const gchar *label_text;
+ gint index, x_layout, y_layout;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ label = GTK_LABEL (widget);
+
+ gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
+ label_text = gtk_label_get_text (label);
+ index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
+ pango_layout_index_to_pos (gtk_label_get_layout (label), index, &char_rect);
+
+ gail_misc_get_extents_from_pango_rectangle (widget, &char_rect,
+ x_layout, y_layout, x, y, width, height, coords);
+}
+
+static gint
+gail_label_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+ const gchar *label_text;
+ gint index, x_layout, y_layout;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+ label = GTK_LABEL (widget);
+
+ gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
+
+ index = gail_misc_get_index_at_point_in_layout (widget,
+ gtk_label_get_layout (label),
+ x_layout, y_layout, x, y, coords);
+ label_text = gtk_label_get_text (label);
+ if (index == -1)
+ {
+ if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
+ return g_utf8_strlen (label_text, -1);
+
+ return index;
+ }
+ else
+ return g_utf8_pointer_to_offset (label_text, label_text + index);
+}
+
+static AtkAttributeSet*
+gail_label_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+ AtkAttributeSet *at_set = NULL;
+ GtkJustification justify;
+ GtkTextDirection dir;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = GTK_LABEL (widget);
+
+ /* Get values set for entire label, if any */
+ justify = gtk_label_get_justify (label);
+ if (justify != GTK_JUSTIFY_CENTER)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_JUSTIFICATION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
+ }
+ dir = gtk_widget_get_direction (widget);
+ if (dir == GTK_TEXT_DIR_RTL)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_DIRECTION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
+ }
+
+ at_set = gail_misc_layout_get_run_attributes (at_set,
+ gtk_label_get_layout (label),
+ gtk_label_get_text (label),
+ offset,
+ start_offset,
+ end_offset);
+ return at_set;
+}
+
+static AtkAttributeSet*
+gail_label_get_default_attributes (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+ AtkAttributeSet *at_set = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = GTK_LABEL (widget);
+
+ at_set = gail_misc_get_default_attributes (at_set,
+ gtk_label_get_layout (label),
+ widget);
+ return at_set;
+}
+
+static gunichar
+gail_label_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GtkWidget *widget;
+ GtkLabel *label;
+ const gchar *string;
+ gchar *index;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return '\0';
+
+ label = GTK_LABEL (widget);
+ string = gtk_label_get_text (label);
+ if (offset >= g_utf8_strlen (string, -1))
+ return '\0';
+ index = g_utf8_offset_to_pointer (string, offset);
+
+ return g_utf8_get_char (index);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_LABEL_H__
+#define __GAIL_LABEL_H__
+
+#include "gailwidget.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_LABEL (gail_label_get_type ())
+#define GAIL_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_LABEL, GailLabel))
+#define GAIL_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_LABEL, GailLabelClass))
+#define GAIL_IS_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_LABEL))
+#define GAIL_IS_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_LABEL))
+#define GAIL_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_LABEL, GailLabelClass))
+
+typedef struct _GailLabel GailLabel;
+typedef struct _GailLabelClass GailLabelClass;
+
+struct _GailLabel
+{
+ GailWidget parent;
+
+ GailTextUtil *textutil;
+ gint cursor_position;
+ gint selection_bound;
+ gint label_length;
+ gulong window_create_handler;
+ gboolean has_top_level;
+};
+
+GType gail_label_get_type (void);
+
+struct _GailLabelClass
+{
+ GailWidgetClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_LABEL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gaillinkbutton.h"
+
+typedef struct _GailLinkButtonLink GailLinkButtonLink;
+typedef struct _GailLinkButtonLinkClass GailLinkButtonLinkClass;
+
+struct _GailLinkButtonLink
+{
+ AtkHyperlink parent;
+
+ GailLinkButton *button;
+ gchar *description;
+};
+
+struct _GailLinkButtonLinkClass
+{
+ AtkHyperlinkClass parent_class;
+};
+
+static void atk_action_interface_init (AtkActionIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GailLinkButtonLink, gail_link_button_link, ATK_TYPE_HYPERLINK,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
+
+static gchar *
+gail_link_button_link_get_uri (AtkHyperlink *link,
+ gint i)
+{
+ GailLinkButtonLink *l = (GailLinkButtonLink *)link;
+ GtkWidget *widget;
+ const gchar *uri;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (l->button));
+ uri = gtk_link_button_get_uri (GTK_LINK_BUTTON (widget));
+
+ return g_strdup (uri);
+}
+
+static gint
+gail_link_button_link_get_n_anchors (AtkHyperlink *link)
+{
+ return 1;
+}
+
+static gboolean
+gail_link_button_link_is_valid (AtkHyperlink *link)
+{
+ return TRUE;
+}
+
+static AtkObject *
+gail_link_button_link_get_object (AtkHyperlink *link,
+ gint i)
+{
+ GailLinkButtonLink *l = (GailLinkButtonLink *)link;
+
+ return ATK_OBJECT (l->button);
+}
+
+static gint
+gail_link_button_link_get_start_index (AtkHyperlink *link)
+{
+ return 0;
+}
+
+static gint
+gail_link_button_link_get_end_index (AtkHyperlink *link)
+{
+ GailLinkButtonLink *l = (GailLinkButtonLink *)link;
+
+ return atk_text_get_character_count (ATK_TEXT (l->button));
+}
+
+static void
+gail_link_button_link_init (GailLinkButtonLink *link)
+{
+ link->description = NULL;
+}
+
+static void
+gail_link_button_link_finalize (GObject *obj)
+{
+ GailLinkButtonLink *link = (GailLinkButtonLink *)obj;
+
+ g_free (link->description);
+
+ G_OBJECT_CLASS (gail_link_button_link_parent_class)->finalize (obj);
+}
+
+static void
+gail_link_button_link_class_init (GailLinkButtonLinkClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ AtkHyperlinkClass *hyperlink_class = ATK_HYPERLINK_CLASS (class);
+
+ object_class->finalize = gail_link_button_link_finalize;
+
+ hyperlink_class->get_uri = gail_link_button_link_get_uri;
+ hyperlink_class->get_n_anchors = gail_link_button_link_get_n_anchors;
+ hyperlink_class->is_valid = gail_link_button_link_is_valid;
+ hyperlink_class->get_object = gail_link_button_link_get_object;
+ hyperlink_class->get_start_index = gail_link_button_link_get_start_index;
+ hyperlink_class->get_end_index = gail_link_button_link_get_end_index;
+}
+
+static gboolean
+gail_link_button_link_do_action (AtkAction *action,
+ gint i)
+{
+ GailLinkButtonLink *link = (GailLinkButtonLink *)action;
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (link->button);
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ gtk_button_clicked (GTK_BUTTON (widget));
+
+ return TRUE;
+}
+
+static gint
+gail_link_button_link_get_n_actions (AtkAction *action)
+{
+ return 1;
+}
+
+static const gchar *
+gail_link_button_link_get_name (AtkAction *action,
+ gint i)
+{
+ g_return_val_if_fail (i == 0, NULL);
+
+ return "activate";
+}
+
+static const gchar *
+gail_link_button_link_get_description (AtkAction *action,
+ gint i)
+{
+ GailLinkButtonLink *link = (GailLinkButtonLink *)action;
+
+ g_return_val_if_fail (i == 0, NULL);
+
+ return link->description;
+}
+
+static gboolean
+gail_link_button_link_set_description (AtkAction *action,
+ gint i,
+ const gchar *description)
+{
+ GailLinkButtonLink *link = (GailLinkButtonLink *)action;
+
+ g_return_val_if_fail (i == 0, FALSE);
+
+ g_free (link->description);
+ link->description = g_strdup (description);
+
+ return TRUE;
+}
+
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ iface->do_action = gail_link_button_link_do_action;
+ iface->get_n_actions = gail_link_button_link_get_n_actions;
+ iface->get_name = gail_link_button_link_get_name;
+ iface->get_description = gail_link_button_link_get_description;
+ iface->set_description = gail_link_button_link_set_description;
+}
+
+static gboolean
+activate_link (GtkLinkButton *button, AtkHyperlink *link)
+{
+ g_signal_emit_by_name (link, "link-activated");
+
+ return FALSE;
+}
+
+static AtkHyperlink *
+gail_link_button_get_hyperlink (AtkHyperlinkImpl *impl)
+{
+ GailLinkButton *button = GAIL_LINK_BUTTON (impl);
+
+ if (!button->link)
+ {
+ button->link = g_object_new (gail_link_button_link_get_type (), NULL);
+ g_signal_connect (gtk_accessible_get_widget (GTK_ACCESSIBLE (button)),
+ "activate-link", G_CALLBACK (activate_link), button->link);
+ }
+
+ return button->link;
+}
+
+static void atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GailLinkButton, gail_link_button, GAIL_TYPE_BUTTON,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERLINK_IMPL, atk_hypertext_impl_interface_init))
+
+static void
+gail_link_button_init (GailLinkButton *button)
+{
+}
+
+static void
+gail_link_button_finalize (GObject *object)
+{
+ GailLinkButton *button = GAIL_LINK_BUTTON (object);
+
+ if (button->link)
+ g_object_unref (button->link);
+
+ G_OBJECT_CLASS (gail_link_button_parent_class)->finalize (object);
+}
+
+static void
+gail_link_button_class_init (GailLinkButtonClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = gail_link_button_finalize;
+}
+
+static void
+atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface)
+{
+ iface->get_hyperlink = gail_link_button_get_hyperlink;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_LINK_BUTTON_H__
+#define __GAIL_LINK_BUTTON_H__
+
+#include "gailbutton.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_LINK_BUTTON (gail_link_button_get_type ())
+#define GAIL_LINK_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_LINK_BUTTON, GailLinkButton))
+#define GAIL_LINK_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_LINK_BUTTON, GailLinkButtonClass))
+#define GAIL_IS_LINK_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_LINK_BUTTON))
+#define GAIL_IS_LINK_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_LINK_BUTTON))
+#define GAIL_LINK_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_LINK_BUTTON, GailLinkButtonClass))
+
+typedef struct _GailLinkButton GailLinkButton;
+typedef struct _GailLinkButtonClass GailLinkButtonClass;
+
+struct _GailLinkButton
+{
+ GailButton parent;
+
+ AtkHyperlink *link;
+};
+
+GType gail_link_button_get_type (void);
+
+struct _GailLinkButtonClass
+{
+ GailButtonClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_LINK_BUTTON_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gailmenu.h"
+
+static void gail_menu_class_init (GailMenuClass *klass);
+static void gail_menu_init (GailMenu *accessible);
+
+static void gail_menu_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static AtkObject* gail_menu_get_parent (AtkObject *accessible);
+static gint gail_menu_get_index_in_parent (AtkObject *accessible);
+
+G_DEFINE_TYPE (GailMenu, gail_menu, GAIL_TYPE_MENU_SHELL)
+
+static void
+gail_menu_class_init (GailMenuClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->get_parent = gail_menu_get_parent;
+ class->get_index_in_parent = gail_menu_get_index_in_parent;
+ class->initialize = gail_menu_real_initialize;
+}
+
+static void
+gail_menu_init (GailMenu *accessible)
+{
+}
+
+static void
+gail_menu_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_menu_parent_class)->initialize (obj, data);
+
+ obj->role = ATK_ROLE_MENU;
+
+ g_object_set_data (G_OBJECT (obj), "atk-component-layer",
+ GINT_TO_POINTER (ATK_LAYER_POPUP));
+}
+
+static AtkObject*
+gail_menu_get_parent (AtkObject *accessible)
+{
+ AtkObject *parent;
+
+ parent = accessible->accessible_parent;
+
+ if (parent != NULL)
+ {
+ g_return_val_if_fail (ATK_IS_OBJECT (parent), NULL);
+ }
+ else
+ {
+ GtkWidget *widget, *parent_widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ {
+ /*
+ * State is defunct
+ */
+ return NULL;
+ }
+ g_return_val_if_fail (GTK_IS_MENU (widget), NULL);
+
+ /*
+ * If the menu is attached to a menu item or a button (Gnome Menu)
+ * report the menu item as parent.
+ */
+ parent_widget = gtk_menu_get_attach_widget (GTK_MENU (widget));
+
+ if (!GTK_IS_MENU_ITEM (parent_widget) && !GTK_IS_BUTTON (parent_widget) && !GTK_IS_COMBO_BOX (parent_widget))
+ parent_widget = gtk_widget_get_parent (widget);
+
+ if (parent_widget == NULL)
+ return NULL;
+
+ parent = gtk_widget_get_accessible (parent_widget);
+ atk_object_set_parent (accessible, parent);
+ }
+ return parent;
+}
+
+static gint
+gail_menu_get_index_in_parent (AtkObject *accessible)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ {
+ /*
+ * State is defunct
+ */
+ return -1;
+ }
+ g_return_val_if_fail (GTK_IS_MENU (widget), -1);
+
+ if (gtk_menu_get_attach_widget (GTK_MENU (widget)))
+ {
+ return 0;
+ }
+ return ATK_OBJECT_CLASS (gail_menu_parent_class)->get_index_in_parent (accessible);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_MENU_H__
+#define __GAIL_MENU_H__
+
+#include "gailmenushell.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_MENU (gail_menu_get_type ())
+#define GAIL_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_MENU_SHELL, GailMenu))
+#define GAIL_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_MENU, GailMenuClass))
+#define GAIL_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_MENU))
+#define GAIL_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_MENU))
+#define GAIL_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_MENU, GailMenuClass))
+
+typedef struct _GailMenu GailMenu;
+typedef struct _GailMenuClass GailMenuClass;
+
+struct _GailMenu
+{
+ GailMenuShell parent;
+};
+
+GType gail_menu_get_type (void);
+
+struct _GailMenuClass
+{
+ GailMenuShellClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_MENU_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "gailmenuitem.h"
+#include "gailsubmenuitem.h"
+#include <libgail-util/gailmisc.h>
+
+#define KEYBINDING_SEPARATOR ";"
+
+static void gail_menu_item_class_init (GailMenuItemClass *klass);
+static void gail_menu_item_init (GailMenuItem *menu_item);
+
+static void gail_menu_item_real_initialize
+ (AtkObject *obj,
+ gpointer data);
+static gint gail_menu_item_get_n_children (AtkObject *obj);
+static AtkObject* gail_menu_item_ref_child (AtkObject *obj,
+ gint i);
+static AtkStateSet* gail_menu_item_ref_state_set (AtkObject *obj);
+static void gail_menu_item_finalize (GObject *object);
+static void gail_menu_item_label_map_gtk (GtkWidget *widget,
+ gpointer data);
+static void gail_menu_item_init_textutil (GailMenuItem *item,
+ GtkWidget *label);
+static void gail_menu_item_notify_label_gtk (GObject *obj,
+ GParamSpec *pspec,
+ gpointer data);
+static const gchar * gail_menu_item_get_name (AtkObject *object);
+
+
+static void atk_action_interface_init (AtkActionIface *iface);
+static gboolean gail_menu_item_do_action (AtkAction *action,
+ gint i);
+static gboolean idle_do_action (gpointer data);
+static gint gail_menu_item_get_n_actions (AtkAction *action);
+static const gchar* gail_menu_item_get_description(AtkAction *action,
+ gint i);
+static const gchar* gail_menu_item_action_get_name (AtkAction *action,
+ gint i);
+static const gchar* gail_menu_item_get_keybinding (AtkAction *action,
+ gint i);
+static gboolean gail_menu_item_set_description(AtkAction *action,
+ gint i,
+ const gchar *desc);
+static void menu_item_select (GtkMenuItem *item);
+static void menu_item_deselect (GtkMenuItem *item);
+static void menu_item_selection (GtkMenuItem *item,
+ gboolean selected);
+static gboolean find_accel (GtkAccelKey *key,
+ GClosure *closure,
+ gpointer data);
+static gboolean find_accel_new (GtkAccelKey *key,
+ GClosure *closure,
+ gpointer data);
+/* atktext.h */
+static void atk_text_interface_init (AtkTextIface *iface);
+
+static gchar* gail_menu_item_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gunichar gail_menu_item_get_character_at_offset (AtkText *text,
+ gint offset);
+static gchar* gail_menu_item_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_menu_item_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_menu_item_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gint gail_menu_item_get_character_count (AtkText *text);
+static void gail_menu_item_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static gint gail_menu_item_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static AtkAttributeSet* gail_menu_item_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet* gail_menu_item_get_default_attributes (AtkText *text);
+static GtkWidget* get_label_from_container (GtkWidget *container);
+static gchar * get_text_from_label_widget (GtkWidget *widget);
+
+
+G_DEFINE_TYPE_WITH_CODE (GailMenuItem, gail_menu_item, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
+
+static void
+gail_menu_item_class_init (GailMenuItemClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = gail_menu_item_finalize;
+
+ class->get_n_children = gail_menu_item_get_n_children;
+ class->ref_child = gail_menu_item_ref_child;
+ class->ref_state_set = gail_menu_item_ref_state_set;
+ class->initialize = gail_menu_item_real_initialize;
+ class->get_name = gail_menu_item_get_name;
+}
+
+static void
+gail_menu_item_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkWidget *widget;
+ GtkWidget *parent;
+ GailMenuItem *item = GAIL_MENU_ITEM (obj);
+ GtkWidget *label;
+
+ ATK_OBJECT_CLASS (gail_menu_item_parent_class)->initialize (obj, data);
+
+ item->textutil = NULL;
+ item->text = NULL;
+
+ label = get_label_from_container (GTK_WIDGET (data));
+ if (gtk_widget_get_mapped (label))
+ gail_menu_item_init_textutil (item, label);
+ else
+ g_signal_connect (label,
+ "map",
+ G_CALLBACK (gail_menu_item_label_map_gtk),
+ item);
+
+ g_signal_connect (data,
+ "select",
+ G_CALLBACK (menu_item_select),
+ NULL);
+ g_signal_connect (data,
+ "deselect",
+ G_CALLBACK (menu_item_deselect),
+ NULL);
+ widget = GTK_WIDGET (data);
+ parent = gtk_widget_get_parent (widget);
+ if (GTK_IS_MENU (parent))
+ {
+ GtkWidget *parent_widget;
+
+ parent_widget = gtk_menu_get_attach_widget (GTK_MENU (parent));
+
+ if (!GTK_IS_MENU_ITEM (parent_widget))
+ parent_widget = gtk_widget_get_parent (widget);
+ if (parent_widget)
+ {
+ atk_object_set_parent (obj, gtk_widget_get_accessible (parent_widget));
+ }
+ }
+ g_object_set_data (G_OBJECT (obj), "atk-component-layer",
+ GINT_TO_POINTER (ATK_LAYER_POPUP));
+
+ if (GTK_IS_TEAROFF_MENU_ITEM (data))
+ obj->role = ATK_ROLE_TEAR_OFF_MENU_ITEM;
+ else if (GTK_IS_SEPARATOR_MENU_ITEM (data))
+ obj->role = ATK_ROLE_SEPARATOR;
+ else
+ obj->role = ATK_ROLE_MENU_ITEM;
+}
+
+static void
+gail_menu_item_init (GailMenuItem *menu_item)
+{
+ menu_item->click_keybinding = NULL;
+ menu_item->click_description = NULL;
+}
+
+static void
+gail_menu_item_label_map_gtk (GtkWidget *widget,
+ gpointer data)
+{
+ GailMenuItem *item;
+
+ item = GAIL_MENU_ITEM (data);
+ gail_menu_item_init_textutil (item, widget);
+}
+
+static void
+gail_menu_item_notify_label_gtk (GObject *obj,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ AtkObject* atk_obj = ATK_OBJECT (data);
+ GtkLabel *label;
+ GailMenuItem *menu_item;
+
+ if (strcmp (pspec->name, "label") == 0)
+ {
+ const gchar* label_text;
+
+ label = GTK_LABEL (obj);
+
+ label_text = gtk_label_get_text (label);
+
+ menu_item = GAIL_MENU_ITEM (atk_obj);
+ gail_text_util_text_setup (menu_item->textutil, label_text);
+
+ if (atk_obj->name == NULL)
+ {
+ /*
+ * The label has changed so notify a change in accessible-name
+ */
+ g_object_notify (G_OBJECT (atk_obj), "accessible-name");
+ }
+ /*
+ * The label is the only property which can be changed
+ */
+ g_signal_emit_by_name (atk_obj, "visible_data_changed");
+ }
+}
+
+static void
+gail_menu_item_init_textutil (GailMenuItem *item,
+ GtkWidget *label)
+{
+ const gchar *label_text;
+
+ if (item->textutil == NULL)
+ {
+ item->textutil = gail_text_util_new ();
+ g_signal_connect (label,
+ "notify",
+ (GCallback) gail_menu_item_notify_label_gtk,
+ item);
+ }
+ label_text = get_text_from_label_widget (label);
+ gail_text_util_text_setup (item->textutil, label_text);
+}
+
+/* atktext.h */
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_menu_item_get_text;
+ iface->get_character_at_offset = gail_menu_item_get_character_at_offset;
+ iface->get_text_before_offset = gail_menu_item_get_text_before_offset;
+ iface->get_text_at_offset = gail_menu_item_get_text_at_offset;
+ iface->get_text_after_offset = gail_menu_item_get_text_after_offset;
+ iface->get_character_count = gail_menu_item_get_character_count;
+ iface->get_character_extents = gail_menu_item_get_character_extents;
+ iface->get_offset_at_point = gail_menu_item_get_offset_at_point;
+ iface->get_run_attributes = gail_menu_item_get_run_attributes;
+ iface->get_default_attributes = gail_menu_item_get_default_attributes;
+}
+
+static gchar*
+gail_menu_item_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailMenuItem *item;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = get_label_from_container (widget);
+
+ item = GAIL_MENU_ITEM (text);
+ if (!item->textutil)
+ gail_menu_item_init_textutil (item, label);
+
+ label_text = get_text_from_label_widget (label);
+
+ if (label_text == NULL)
+ return NULL;
+ else
+ return gail_text_util_get_substring (item->textutil,
+ start_pos, end_pos);
+}
+
+static gchar*
+gail_menu_item_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailMenuItem *item;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get label */
+ label = get_label_from_container (widget);
+
+ item = GAIL_MENU_ITEM (text);
+ if (!item->textutil)
+ gail_menu_item_init_textutil (item, label);
+
+ return gail_text_util_get_text (item->textutil,
+ NULL, GAIL_BEFORE_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_menu_item_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailMenuItem *item;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get label */
+ label = get_label_from_container (widget);
+
+ item = GAIL_MENU_ITEM (text);
+ if (!item->textutil)
+ gail_menu_item_init_textutil (item, label);
+
+ return gail_text_util_get_text (item->textutil,
+ NULL, GAIL_AT_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_menu_item_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailMenuItem *item;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return NULL;
+ }
+
+ /* Get label */
+ label = get_label_from_container (widget);
+
+ item = GAIL_MENU_ITEM (text);
+ if (!item->textutil)
+ gail_menu_item_init_textutil (item, label);
+
+ return gail_text_util_get_text (item->textutil,
+ NULL, GAIL_AFTER_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gint
+gail_menu_item_get_character_count (AtkText *atk_text)
+{
+ gchar *text;
+ gint len;
+
+ text = gail_menu_item_get_text (atk_text, 0, -1);
+ if (text)
+ {
+ len = g_utf8_strlen (text, -1);
+ g_free (text);
+ }
+ else
+ len = 0;
+
+ return len;
+}
+
+static void
+gail_menu_item_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ PangoRectangle char_rect;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ label = get_label_from_container (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
+ pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
+
+ gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
+ x_layout, y_layout, x, y, width, height, coords);
+}
+
+static gint
+gail_menu_item_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ label = get_label_from_container (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return -1;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+
+ index = gail_misc_get_index_at_point_in_layout (label,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ x_layout, y_layout, x, y, coords);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ if (index == -1)
+ {
+ if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
+ return g_utf8_strlen (label_text, -1);
+
+ return index;
+ }
+ else
+ return g_utf8_pointer_to_offset (label_text, label_text + index);
+}
+
+static AtkAttributeSet*
+gail_menu_item_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkAttributeSet *at_set = NULL;
+ GtkJustification justify;
+ GtkTextDirection dir;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = get_label_from_container (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ /* Get values set for entire label, if any */
+ justify = gtk_label_get_justify (GTK_LABEL (label));
+ if (justify != GTK_JUSTIFY_CENTER)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_JUSTIFICATION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
+ }
+ dir = gtk_widget_get_direction (label);
+ if (dir == GTK_TEXT_DIR_RTL)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_DIRECTION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
+ }
+
+ at_set = gail_misc_layout_get_run_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ (gchar *) gtk_label_get_text (GTK_LABEL (label)),
+ offset,
+ start_offset,
+ end_offset);
+ return at_set;
+}
+
+static AtkAttributeSet*
+gail_menu_item_get_default_attributes (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkAttributeSet *at_set = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = get_label_from_container (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ at_set = gail_misc_get_default_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ widget);
+ return at_set;
+}
+
+static gunichar
+gail_menu_item_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ gchar *string;
+ gchar *index;
+ gunichar ch;
+
+ string = gail_menu_item_get_text (text, 0, -1);
+
+ if (string == NULL || offset >= g_utf8_strlen (string, -1))
+ ch = '\0';
+ else
+ {
+ index = g_utf8_offset_to_pointer (string, offset);
+ ch = g_utf8_get_char (index);
+ }
+
+ g_free (string);
+
+ return ch;
+}
+
+static GtkWidget*
+get_label_from_container (GtkWidget *container)
+{
+ GtkWidget *label;
+ GList *children, *tmp_list;
+
+ if (!GTK_IS_CONTAINER (container))
+ return NULL;
+
+ children = gtk_container_get_children (GTK_CONTAINER (container));
+ label = NULL;
+
+ for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
+ {
+ if (GTK_IS_LABEL (tmp_list->data))
+ {
+ label = tmp_list->data;
+ break;
+ }
+ else if (GTK_IS_CELL_VIEW (tmp_list->data))
+ {
+ label = tmp_list->data;
+ break;
+ }
+ /*
+ * * Get label from menu item in desktop background preferences
+ * * option menu. See bug #144084.
+ * */
+ else if (GTK_IS_BOX (tmp_list->data))
+ {
+ label = get_label_from_container (GTK_WIDGET (tmp_list->data));
+ if (label)
+ break;
+ }
+ }
+ g_list_free (children);
+
+ return label;
+}
+
+static gchar *
+get_text_from_label_widget (GtkWidget *label)
+{
+ if (GTK_IS_LABEL (label))
+ return g_strdup (gtk_label_get_text (GTK_LABEL (label)));
+ else if (GTK_IS_CELL_VIEW (label))
+ {
+ GList *cells, *l;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GtkCellArea *area;
+ gchar *text;
+
+ model = gtk_cell_view_get_model (GTK_CELL_VIEW (label));
+ path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (label));
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+
+ area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (label));
+
+ gtk_cell_area_apply_attributes (area, model, &iter, FALSE, FALSE);
+
+ cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (label));
+ for (l = cells; l; l = l->next)
+ {
+ GtkCellRenderer *cell = l->data;
+
+ if (GTK_IS_CELL_RENDERER_TEXT (cell))
+ {
+ g_object_get (cell, "text", &text, NULL);
+ break;
+ }
+ }
+
+ g_list_free (cells);
+
+ return text;
+ }
+
+ return NULL;
+}
+
+AtkObject*
+gail_menu_item_new (GtkWidget *widget)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), NULL);
+
+ if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)))
+ return gail_sub_menu_item_new (widget);
+
+ object = g_object_new (GAIL_TYPE_MENU_ITEM, NULL);
+
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, widget);
+
+ return accessible;
+}
+
+GList *
+get_children (GtkWidget *submenu)
+{
+ GList *children;
+
+ children = gtk_container_get_children (GTK_CONTAINER (submenu));
+ if (g_list_length (children) == 0)
+ {
+ /*
+ * If menu is empty it may be because the menu items are created only
+ * on demand. For example, in gnome-panel the menu items are created
+ * only when "show" signal is emitted on the menu.
+ *
+ * The following hack forces the menu items to be created.
+ */
+ if (!gtk_widget_get_visible (submenu))
+ {
+ /* FIXME GTK_WIDGET_SET_FLAGS (submenu, GTK_VISIBLE); */
+ g_signal_emit_by_name (submenu, "show");
+ /* FIXME GTK_WIDGET_UNSET_FLAGS (submenu, GTK_VISIBLE); */
+ }
+ g_list_free (children);
+ children = gtk_container_get_children (GTK_CONTAINER (submenu));
+ }
+ return children;
+}
+
+/*
+ * If a menu item has a submenu return the items of the submenu as the
+ * accessible children; otherwise expose no accessible children.
+ */
+static gint
+gail_menu_item_get_n_children (AtkObject* obj)
+{
+ GtkWidget *widget;
+ GtkWidget *submenu;
+ gint count = 0;
+
+ g_return_val_if_fail (GAIL_IS_MENU_ITEM (obj), count);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return count;
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (submenu)
+ {
+ GList *children;
+
+ children = get_children (submenu);
+ count = g_list_length (children);
+ g_list_free (children);
+ }
+ return count;
+}
+
+static AtkObject*
+gail_menu_item_ref_child (AtkObject *obj,
+ gint i)
+{
+ AtkObject *accessible;
+ GtkWidget *widget;
+ GtkWidget *submenu;
+
+ g_return_val_if_fail (GAIL_IS_MENU_ITEM (obj), NULL);
+ g_return_val_if_fail ((i >= 0), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return NULL;
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ if (submenu)
+ {
+ GList *children;
+ GList *tmp_list;
+
+ children = get_children (submenu);
+ tmp_list = g_list_nth (children, i);
+ if (!tmp_list)
+ {
+ g_list_free (children);
+ return NULL;
+ }
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
+ g_list_free (children);
+ g_object_ref (accessible);
+ }
+ else
+ accessible = NULL;
+
+ return accessible;
+}
+
+static AtkStateSet*
+gail_menu_item_ref_state_set (AtkObject *obj)
+{
+ AtkObject *menu_item;
+ AtkStateSet *state_set, *parent_state_set;
+
+ state_set = ATK_OBJECT_CLASS (gail_menu_item_parent_class)->ref_state_set (obj);
+
+ menu_item = atk_object_get_parent (obj);
+
+ if (menu_item)
+ {
+ if (!GTK_IS_MENU_ITEM (gtk_accessible_get_widget (GTK_ACCESSIBLE (menu_item))))
+ return state_set;
+
+ parent_state_set = atk_object_ref_state_set (menu_item);
+ if (!atk_state_set_contains_state (parent_state_set, ATK_STATE_SELECTED))
+ {
+ atk_state_set_remove_state (state_set, ATK_STATE_FOCUSED);
+ atk_state_set_remove_state (state_set, ATK_STATE_SHOWING);
+ }
+ }
+ return state_set;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ iface->do_action = gail_menu_item_do_action;
+ iface->get_n_actions = gail_menu_item_get_n_actions;
+ iface->get_description = gail_menu_item_get_description;
+ iface->get_name = gail_menu_item_action_get_name;
+ iface->get_keybinding = gail_menu_item_get_keybinding;
+ iface->set_description = gail_menu_item_set_description;
+}
+
+static gboolean
+gail_menu_item_do_action (AtkAction *action,
+ gint i)
+{
+ if (i == 0)
+ {
+ GtkWidget *item;
+ GailMenuItem *gail_menu_item;
+
+ item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
+ if (item == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ if (!gtk_widget_get_sensitive (item) || !gtk_widget_get_visible (item))
+ return FALSE;
+
+ gail_menu_item = GAIL_MENU_ITEM (action);
+ if (gail_menu_item->action_idle_handler)
+ return FALSE;
+ else
+ {
+ gail_menu_item->action_idle_handler =
+ gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE,
+ idle_do_action,
+ g_object_ref (gail_menu_item),
+ (GDestroyNotify) g_object_unref);
+ }
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+ensure_menus_unposted (GailMenuItem *menu_item)
+{
+ AtkObject *parent;
+ GtkWidget *widget;
+
+ parent = atk_object_get_parent (ATK_OBJECT (menu_item));
+ while (parent)
+ {
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
+ if (GTK_IS_MENU (widget))
+ {
+ if (gtk_widget_get_mapped (widget))
+ gtk_menu_shell_cancel (GTK_MENU_SHELL (widget));
+
+ return;
+ }
+ parent = atk_object_get_parent (parent);
+ }
+}
+
+static gboolean
+idle_do_action (gpointer data)
+{
+ GtkWidget *item;
+ GtkWidget *item_parent;
+ GailMenuItem *menu_item;
+ gboolean item_mapped;
+
+ menu_item = GAIL_MENU_ITEM (data);
+ menu_item->action_idle_handler = 0;
+ item = gtk_accessible_get_widget (GTK_ACCESSIBLE (menu_item));
+ if (item == NULL /* State is defunct */ ||
+ !gtk_widget_get_sensitive (item) || !gtk_widget_get_visible (item))
+ return FALSE;
+
+ item_parent = gtk_widget_get_parent (item);
+ gtk_menu_shell_select_item (GTK_MENU_SHELL (item_parent), item);
+ item_mapped = gtk_widget_get_mapped (item);
+ /*
+ * This is what is called when <Return> is pressed for a menu item
+ */
+ g_signal_emit_by_name (item_parent, "activate_current",
+ /*force_hide*/ 1);
+ if (!item_mapped)
+ ensure_menus_unposted (menu_item);
+
+ return FALSE;
+}
+
+static gint
+gail_menu_item_get_n_actions (AtkAction *action)
+{
+ /*
+ * Menu item has 1 action
+ */
+ return 1;
+}
+
+static const gchar*
+gail_menu_item_get_description (AtkAction *action,
+ gint i)
+{
+ if (i == 0)
+ {
+ GailMenuItem *item;
+
+ item = GAIL_MENU_ITEM (action);
+ return item->click_description;
+ }
+ else
+ return NULL;
+}
+
+static const gchar*
+gail_menu_item_action_get_name (AtkAction *action,
+ gint i)
+{
+ if (i == 0)
+ return "click";
+ else
+ return NULL;
+}
+
+static const gchar*
+gail_menu_item_get_keybinding (AtkAction *action,
+ gint i)
+{
+ /*
+ * This function returns a string of the form A;B;C where
+ * A is the keybinding for the widget; B is the keybinding to traverse
+ * from the menubar and C is the accelerator.
+ * The items in the keybinding to traverse from the menubar are separated
+ * by ":".
+ */
+ GailMenuItem *gail_menu_item;
+ gchar *keybinding = NULL;
+ gchar *item_keybinding = NULL;
+ gchar *full_keybinding = NULL;
+ gchar *accelerator = NULL;
+
+ gail_menu_item = GAIL_MENU_ITEM (action);
+ if (i == 0)
+ {
+ GtkWidget *item;
+ GtkWidget *temp_item;
+ GtkWidget *child;
+ GtkWidget *parent;
+
+ item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
+ if (item == NULL)
+ /* State is defunct */
+ return NULL;
+
+ temp_item = item;
+ while (TRUE)
+ {
+ GdkModifierType mnemonic_modifier = 0;
+ guint key_val;
+ gchar *key, *temp_keybinding;
+
+ child = gtk_bin_get_child (GTK_BIN (temp_item));
+ if (child == NULL)
+ {
+ /* Possibly a tear off menu item; it could also be a menu
+ * separator generated by gtk_item_factory_create_items()
+ */
+ return NULL;
+ }
+ parent = gtk_widget_get_parent (temp_item);
+ if (!parent)
+ {
+ /*
+ * parent can be NULL when activating a window from the panel
+ */
+ return NULL;
+ }
+ g_return_val_if_fail (GTK_IS_MENU_SHELL (parent), NULL);
+ if (GTK_IS_MENU_BAR (parent))
+ {
+ GtkWidget *toplevel;
+
+ toplevel = gtk_widget_get_toplevel (parent);
+ if (toplevel && GTK_IS_WINDOW (toplevel))
+ mnemonic_modifier = gtk_window_get_mnemonic_modifier (
+ GTK_WINDOW (toplevel));
+ }
+ if (GTK_IS_LABEL (child))
+ {
+ key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (child));
+ if (key_val != GDK_KEY_VoidSymbol)
+ {
+ key = gtk_accelerator_name (key_val, mnemonic_modifier);
+ if (full_keybinding)
+ temp_keybinding = g_strconcat (key, ":", full_keybinding, NULL);
+ else
+ temp_keybinding = g_strconcat (key, NULL);
+ if (temp_item == item)
+ {
+ item_keybinding = g_strdup (key);
+ }
+ g_free (key);
+ g_free (full_keybinding);
+ full_keybinding = temp_keybinding;
+ }
+ else
+ {
+ /* No keybinding */
+ g_free (full_keybinding);
+ full_keybinding = NULL;
+ break;
+ }
+ }
+ if (GTK_IS_MENU_BAR (parent))
+ /* We have reached the menu bar so we are finished */
+ break;
+ g_return_val_if_fail (GTK_IS_MENU (parent), NULL);
+ temp_item = gtk_menu_get_attach_widget (GTK_MENU (parent));
+ if (!GTK_IS_MENU_ITEM (temp_item))
+ {
+ /*
+ * Menu is attached to something other than a menu item;
+ * probably an option menu
+ */
+ g_free (full_keybinding);
+ full_keybinding = NULL;
+ break;
+ }
+ }
+
+ parent = gtk_widget_get_parent (item);
+ if (GTK_IS_MENU (parent))
+ {
+ GtkAccelGroup *group;
+ GtkAccelKey *key;
+
+ group = gtk_menu_get_accel_group (GTK_MENU (parent));
+
+ if (group)
+ {
+ key = gtk_accel_group_find (group, find_accel, item);
+ }
+ else
+ {
+ /*
+ * If the menu item is created using GtkAction and GtkUIManager
+ * we get here.
+ */
+ key = NULL;
+ child = gtk_bin_get_child (GTK_BIN (item));
+ if (GTK_IS_ACCEL_LABEL (child))
+ {
+ GtkAccelLabel *accel_label;
+ GClosure *accel_closure;
+
+ accel_label = GTK_ACCEL_LABEL (child);
+ g_object_get (accel_label,
+ "accel-closure", &accel_closure,
+ NULL);
+ if (accel_closure)
+ {
+ key = gtk_accel_group_find (gtk_accel_group_from_accel_closure (accel_closure),
+ find_accel_new,
+ accel_closure);
+ }
+
+ }
+ }
+
+ if (key)
+ {
+ accelerator = gtk_accelerator_name (key->accel_key,
+ key->accel_mods);
+ }
+ }
+ }
+ /*
+ * Concatenate the bindings
+ */
+ if (item_keybinding || full_keybinding || accelerator)
+ {
+ gchar *temp;
+ if (item_keybinding)
+ {
+ keybinding = g_strconcat (item_keybinding, KEYBINDING_SEPARATOR, NULL);
+ g_free (item_keybinding);
+ }
+ else
+ keybinding = g_strconcat (KEYBINDING_SEPARATOR, NULL);
+
+ if (full_keybinding)
+ {
+ temp = g_strconcat (keybinding, full_keybinding,
+ KEYBINDING_SEPARATOR, NULL);
+ g_free (full_keybinding);
+ }
+ else
+ temp = g_strconcat (keybinding, KEYBINDING_SEPARATOR, NULL);
+
+ g_free (keybinding);
+ keybinding = temp;
+ if (accelerator)
+ {
+ temp = g_strconcat (keybinding, accelerator, NULL);
+ g_free (accelerator);
+ g_free (keybinding);
+ keybinding = temp;
+ }
+ }
+ g_free (gail_menu_item->click_keybinding);
+ gail_menu_item->click_keybinding = keybinding;
+ return keybinding;
+}
+
+static gboolean
+gail_menu_item_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc)
+{
+ if (i == 0)
+ {
+ GailMenuItem *item;
+
+ item = GAIL_MENU_ITEM (action);
+ g_free (item->click_description);
+ item->click_description = g_strdup (desc);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+gail_menu_item_finalize (GObject *object)
+{
+ GailMenuItem *menu_item = GAIL_MENU_ITEM (object);
+
+ g_free (menu_item->click_keybinding);
+ g_free (menu_item->click_description);
+ if (menu_item->action_idle_handler)
+ {
+ g_source_remove (menu_item->action_idle_handler);
+ menu_item->action_idle_handler = 0;
+ }
+
+ if (menu_item->textutil)
+ {
+ g_object_unref (menu_item->textutil);
+ }
+ if (menu_item->text)
+ {
+ g_free (menu_item->text);
+ menu_item->text = NULL;
+ }
+
+ G_OBJECT_CLASS (gail_menu_item_parent_class)->finalize (object);
+}
+
+static const gchar *
+gail_menu_item_get_name (AtkObject *obj)
+{
+ const gchar* name;
+ GtkWidget *widget;
+ GtkWidget *label;
+
+ name = ATK_OBJECT_CLASS (gail_menu_item_parent_class)->get_name (obj);
+
+ if (name)
+ return name;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return NULL;
+
+ label = get_label_from_container (widget);
+ if (GTK_IS_LABEL (label))
+ return gtk_label_get_text (GTK_LABEL(label));
+
+ return NULL;
+}
+
+static void
+menu_item_select (GtkMenuItem *item)
+{
+ menu_item_selection (item, TRUE);
+}
+
+static void
+menu_item_deselect (GtkMenuItem *item)
+{
+ menu_item_selection (item, FALSE);
+}
+
+static void
+menu_item_selection (GtkMenuItem *item,
+ gboolean selected)
+{
+ AtkObject *obj, *parent;
+ gint i;
+
+ obj = gtk_widget_get_accessible (GTK_WIDGET (item));
+ atk_object_notify_state_change (obj, ATK_STATE_SELECTED, selected);
+
+ for (i = 0; i < atk_object_get_n_accessible_children (obj); i++)
+ {
+ AtkObject *child;
+ child = atk_object_ref_accessible_child (obj, i);
+ atk_object_notify_state_change (child, ATK_STATE_SHOWING, selected);
+ g_object_unref (child);
+ }
+ parent = atk_object_get_parent (obj);
+ g_signal_emit_by_name (parent, "selection_changed");
+}
+
+static gboolean
+find_accel (GtkAccelKey *key,
+ GClosure *closure,
+ gpointer data)
+{
+ /*
+ * We assume that closure->data points to the widget
+ * pending gtk_widget_get_accel_closures being made public
+ */
+ return data == (gpointer) closure->data;
+}
+
+static gboolean
+find_accel_new (GtkAccelKey *key,
+ GClosure *closure,
+ gpointer data)
+{
+ return data == (gpointer) closure;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_MENU_ITEM_H__
+#define __GAIL_MENU_ITEM_H__
+
+#include "gailcontainer.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_MENU_ITEM (gail_menu_item_get_type ())
+#define GAIL_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_MENU_ITEM, GailMenuItem))
+#define GAIL_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_MENU_ITEM, GailMenuItemClass))
+#define GAIL_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_MENU_ITEM))
+#define GAIL_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_MENU_ITEM))
+#define GAIL_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_MENU_ITEM, GailMenuItemClass))
+
+typedef struct _GailMenuItem GailMenuItem;
+typedef struct _GailMenuItemClass GailMenuItemClass;
+
+struct _GailMenuItem
+{
+ GailContainer parent;
+
+ GailTextUtil *textutil;
+
+ gchar *text;
+
+ gchar *click_keybinding;
+ gchar *click_description;
+ guint action_idle_handler;
+};
+
+GType gail_menu_item_get_type (void);
+
+struct _GailMenuItemClass
+{
+ GailContainerClass parent_class;
+};
+
+AtkObject* gail_menu_item_new (GtkWidget *widget);
+
+G_END_DECLS
+
+#endif /* __GAIL_MENU_ITEM_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailmenushell.h"
+
+static void gail_menu_shell_class_init (GailMenuShellClass *klass);
+static void gail_menu_shell_init (GailMenuShell *menu_shell);
+static void gail_menu_shell_initialize (AtkObject *accessible,
+ gpointer data);
+static void atk_selection_interface_init (AtkSelectionIface *iface);
+static gboolean gail_menu_shell_add_selection (AtkSelection *selection,
+ gint i);
+static gboolean gail_menu_shell_clear_selection (AtkSelection *selection);
+static AtkObject* gail_menu_shell_ref_selection (AtkSelection *selection,
+ gint i);
+static gint gail_menu_shell_get_selection_count (AtkSelection *selection);
+static gboolean gail_menu_shell_is_child_selected (AtkSelection *selection,
+ gint i);
+static gboolean gail_menu_shell_remove_selection (AtkSelection *selection,
+ gint i);
+
+G_DEFINE_TYPE_WITH_CODE (GailMenuShell, gail_menu_shell, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
+
+static void
+gail_menu_shell_class_init (GailMenuShellClass *klass)
+{
+ AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
+
+ atk_object_class->initialize = gail_menu_shell_initialize;
+}
+
+static void
+gail_menu_shell_init (GailMenuShell *menu_shell)
+{
+}
+
+static void
+gail_menu_shell_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_menu_shell_parent_class)->initialize (accessible, data);
+
+ if (GTK_IS_MENU_BAR (data))
+ accessible->role = ATK_ROLE_MENU_BAR;
+ else
+ /*
+ * Accessible object for Menu is created in gailmenu.c
+ */
+ accessible->role = ATK_ROLE_UNKNOWN;
+}
+
+static void
+atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ iface->add_selection = gail_menu_shell_add_selection;
+ iface->clear_selection = gail_menu_shell_clear_selection;
+ iface->ref_selection = gail_menu_shell_ref_selection;
+ iface->get_selection_count = gail_menu_shell_get_selection_count;
+ iface->is_child_selected = gail_menu_shell_is_child_selected;
+ iface->remove_selection = gail_menu_shell_remove_selection;
+ /*
+ * select_all_selection does not make sense for a menu_shell
+ * so no implementation is provided.
+ */
+}
+
+static gboolean
+gail_menu_shell_add_selection (AtkSelection *selection,
+ gint i)
+{
+ GList *kids;
+ GtkWidget *item;
+ guint length;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return FALSE;
+ }
+
+ kids = gtk_container_get_children (GTK_CONTAINER (widget));
+ length = g_list_length (kids);
+ if (i < 0 || i > length)
+ {
+ g_list_free (kids);
+ return FALSE;
+ }
+
+ item = g_list_nth_data (kids, i);
+ g_list_free (kids);
+ g_return_val_if_fail (GTK_IS_MENU_ITEM(item), FALSE);
+ gtk_menu_shell_select_item (GTK_MENU_SHELL (widget), item);
+ return TRUE;
+}
+
+static gboolean
+gail_menu_shell_clear_selection (AtkSelection *selection)
+{
+ GtkMenuShell *shell;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return FALSE;
+ }
+
+ shell = GTK_MENU_SHELL (widget);
+
+ gtk_menu_shell_deselect (shell);
+ return TRUE;
+}
+
+static AtkObject*
+gail_menu_shell_ref_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ AtkObject *obj;
+ GtkWidget *widget;
+ GtkWidget *item;
+
+ if (i != 0)
+ return NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return NULL;
+ }
+
+ shell = GTK_MENU_SHELL (widget);
+
+ item = gtk_menu_shell_get_selected_item (shell);
+ if (item != NULL)
+ {
+ obj = gtk_widget_get_accessible (item);
+ g_object_ref (obj);
+ return obj;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static gint
+gail_menu_shell_get_selection_count (AtkSelection *selection)
+{
+ GtkMenuShell *shell;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return 0;
+ }
+
+ shell = GTK_MENU_SHELL (widget);
+
+ /*
+ * Identifies the currently selected menu item
+ */
+ if (gtk_menu_shell_get_selected_item (shell) == NULL)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+static gboolean
+gail_menu_shell_is_child_selected (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ GList *kids;
+ gint j;
+ GtkWidget *widget;
+ GtkWidget *item;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return FALSE;
+ }
+
+ shell = GTK_MENU_SHELL (widget);
+ item = gtk_menu_shell_get_selected_item (shell);
+ if (item == NULL)
+ return FALSE;
+
+ kids = gtk_container_get_children (GTK_CONTAINER (shell));
+ j = g_list_index (kids, item);
+ g_list_free (kids);
+
+ return (j==i);
+}
+
+static gboolean
+gail_menu_shell_remove_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ GtkWidget *widget;
+ GtkWidget *item;
+
+ if (i != 0)
+ return FALSE;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return FALSE;
+ }
+
+ shell = GTK_MENU_SHELL (widget);
+
+ item = gtk_menu_shell_get_selected_item (shell);
+ if (item && gtk_menu_item_get_submenu (GTK_MENU_ITEM (item)))
+ {
+ /*
+ * Menu item contains a menu and it is the selected menu item
+ * so deselect it.
+ */
+ gtk_menu_shell_deselect (shell);
+ }
+ return TRUE;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_MENU_SHELL_H__
+#define __GAIL_MENU_SHELL_H__
+
+#include "gailcontainer.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_MENU_SHELL (gail_menu_shell_get_type ())
+#define GAIL_MENU_SHELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_MENU_SHELL, GailMenuShell))
+#define GAIL_MENU_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_MENU_SHELL, GailMenuShellClass))
+#define GAIL_IS_MENU_SHELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_MENU_SHELL))
+#define GAIL_IS_MENU_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_MENU_SHELL))
+#define GAIL_MENU_SHELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_MENU_SHELL, GailMenuShellClass))
+
+typedef struct _GailMenuShell GailMenuShell;
+typedef struct _GailMenuShellClass GailMenuShellClass;
+
+struct _GailMenuShell
+{
+ GailContainer parent;
+};
+
+GType gail_menu_shell_get_type (void);
+
+struct _GailMenuShellClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_MENU_SHELL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailnotebook.h"
+#include "gailnotebookpage.h"
+#include "gail-private-macros.h"
+
+static void gail_notebook_class_init (GailNotebookClass *klass);
+static void gail_notebook_init (GailNotebook *notebook);
+static void gail_notebook_finalize (GObject *object);
+static void gail_notebook_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static void gail_notebook_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+
+static AtkObject* gail_notebook_ref_child (AtkObject *obj,
+ gint i);
+static gint gail_notebook_real_remove_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data);
+static void atk_selection_interface_init (AtkSelectionIface *iface);
+static gboolean gail_notebook_add_selection (AtkSelection *selection,
+ gint i);
+static AtkObject* gail_notebook_ref_selection (AtkSelection *selection,
+ gint i);
+static gint gail_notebook_get_selection_count (AtkSelection *selection);
+static gboolean gail_notebook_is_child_selected (AtkSelection *selection,
+ gint i);
+static AtkObject* find_child_in_list (GList *list,
+ gint index);
+static void check_cache (GailNotebook *gail_notebook,
+ GtkNotebook *notebook);
+static void reset_cache (GailNotebook *gail_notebook,
+ gint index);
+static void create_notebook_page_accessible (GailNotebook *gail_notebook,
+ GtkNotebook *notebook,
+ gint index,
+ gboolean insert_before,
+ GList *list);
+static void gail_notebook_child_parent_set (GtkWidget *widget,
+ GtkWidget *old_parent,
+ gpointer data);
+static gboolean gail_notebook_focus_cb (GtkWidget *widget,
+ GtkDirectionType type);
+static gboolean gail_notebook_check_focus_tab (gpointer data);
+static void gail_notebook_destroyed (gpointer data);
+
+
+G_DEFINE_TYPE_WITH_CODE (GailNotebook, gail_notebook, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
+
+static void
+gail_notebook_class_init (GailNotebookClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailWidgetClass *widget_class;
+ GailContainerClass *container_class;
+
+ widget_class = (GailWidgetClass*)klass;
+ container_class = (GailContainerClass*)klass;
+
+ gobject_class->finalize = gail_notebook_finalize;
+
+ widget_class->notify_gtk = gail_notebook_real_notify_gtk;
+
+ class->ref_child = gail_notebook_ref_child;
+ class->initialize = gail_notebook_real_initialize;
+ /*
+ * We do not provide an implementation of get_n_children
+ * as the implementation in GailContainer returns the correct
+ * number of children.
+ */
+ container_class->remove_gtk = gail_notebook_real_remove_gtk;
+}
+
+static void
+gail_notebook_init (GailNotebook *notebook)
+{
+ notebook->page_cache = NULL;
+ notebook->selected_page = -1;
+ notebook->focus_tab_page = -1;
+ notebook->remove_index = -1;
+ notebook->idle_focus_id = 0;
+}
+
+static AtkObject*
+gail_notebook_ref_child (AtkObject *obj,
+ gint i)
+{
+ AtkObject *accessible = NULL;
+ GailNotebook *gail_notebook;
+ GtkNotebook *gtk_notebook;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ gail_notebook = GAIL_NOTEBOOK (obj);
+
+ gtk_notebook = GTK_NOTEBOOK (widget);
+
+ if (gail_notebook->page_count < gtk_notebook_get_n_pages (gtk_notebook))
+ check_cache (gail_notebook, gtk_notebook);
+
+ accessible = find_child_in_list (gail_notebook->page_cache, i);
+
+ if (accessible != NULL)
+ g_object_ref (accessible);
+
+ return accessible;
+}
+
+static void
+gail_notebook_page_added (GtkNotebook *gtk_notebook,
+ GtkWidget *child,
+ guint page_num,
+ gpointer data)
+{
+ AtkObject *atk_obj;
+ GailNotebook *notebook;
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (gtk_notebook));
+ notebook = GAIL_NOTEBOOK (atk_obj);
+ create_notebook_page_accessible (notebook, gtk_notebook, page_num, FALSE, NULL);
+ notebook->page_count++;
+}
+
+static void
+gail_notebook_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GailNotebook *notebook;
+ GtkNotebook *gtk_notebook;
+ gint i;
+
+ ATK_OBJECT_CLASS (gail_notebook_parent_class)->initialize (obj, data);
+
+ notebook = GAIL_NOTEBOOK (obj);
+ gtk_notebook = GTK_NOTEBOOK (data);
+ for (i = 0; i < gtk_notebook_get_n_pages (gtk_notebook); i++)
+ {
+ create_notebook_page_accessible (notebook, gtk_notebook, i, FALSE, NULL);
+ }
+ notebook->page_count = i;
+ notebook->selected_page = gtk_notebook_get_current_page (gtk_notebook);
+
+ g_signal_connect (gtk_notebook,
+ "focus",
+ G_CALLBACK (gail_notebook_focus_cb),
+ NULL);
+ g_signal_connect (gtk_notebook,
+ "page-added",
+ G_CALLBACK (gail_notebook_page_added),
+ NULL);
+ g_object_weak_ref (G_OBJECT(gtk_notebook),
+ (GWeakNotify) gail_notebook_destroyed,
+ obj);
+
+ obj->role = ATK_ROLE_PAGE_TAB_LIST;
+}
+
+static void
+gail_notebook_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkWidget *widget;
+ AtkObject* atk_obj;
+
+ widget = GTK_WIDGET (obj);
+ atk_obj = gtk_widget_get_accessible (widget);
+
+ if (strcmp (pspec->name, "page") == 0)
+ {
+ gint page_num, old_page_num;
+ gint focus_page_num = 0;
+ gint old_focus_page_num;
+ GailNotebook *gail_notebook;
+ GtkNotebook *gtk_notebook;
+
+ gail_notebook = GAIL_NOTEBOOK (atk_obj);
+ gtk_notebook = GTK_NOTEBOOK (widget);
+
+ if (gail_notebook->page_count < gtk_notebook_get_n_pages (gtk_notebook))
+ check_cache (gail_notebook, gtk_notebook);
+ /*
+ * Notify SELECTED state change for old and new page
+ */
+ old_page_num = gail_notebook->selected_page;
+ page_num = gtk_notebook_get_current_page (gtk_notebook);
+ gail_notebook->selected_page = page_num;
+ gail_notebook->focus_tab_page = page_num;
+ old_focus_page_num = gail_notebook->focus_tab_page;
+
+ if (page_num != old_page_num)
+ {
+ AtkObject *obj;
+
+ if (old_page_num != -1)
+ {
+ obj = gail_notebook_ref_child (atk_obj, old_page_num);
+ if (obj)
+ {
+ atk_object_notify_state_change (obj,
+ ATK_STATE_SELECTED,
+ FALSE);
+ g_object_unref (obj);
+ }
+ }
+ obj = gail_notebook_ref_child (atk_obj, page_num);
+ if (obj)
+ {
+ atk_object_notify_state_change (obj,
+ ATK_STATE_SELECTED,
+ TRUE);
+ g_object_unref (obj);
+ /*
+ * The page which is being displayed has changed but there is
+ * no need to tell the focus tracker as the focus page will also
+ * change or a widget in the page will receive focus if the
+ * Notebook does not have tabs.
+ */
+ }
+ g_signal_emit_by_name (atk_obj, "selection_changed");
+ g_signal_emit_by_name (atk_obj, "visible_data_changed");
+ }
+ if (gtk_notebook_get_show_tabs (gtk_notebook) &&
+ (focus_page_num != old_focus_page_num))
+ {
+ if (gail_notebook->idle_focus_id)
+ g_source_remove (gail_notebook->idle_focus_id);
+ gail_notebook->idle_focus_id = gdk_threads_add_idle (gail_notebook_check_focus_tab, atk_obj);
+ }
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_notebook_parent_class)->notify_gtk (obj, pspec);
+}
+
+static void
+gail_notebook_finalize (GObject *object)
+{
+ GailNotebook *notebook = GAIL_NOTEBOOK (object);
+ GList *list;
+
+ /*
+ * Get rid of the GailNotebookPage objects which we have cached.
+ */
+ list = notebook->page_cache;
+ if (list != NULL)
+ {
+ while (list)
+ {
+ g_object_unref (list->data);
+ list = list->next;
+ }
+ }
+
+ g_list_free (notebook->page_cache);
+
+ if (notebook->idle_focus_id)
+ g_source_remove (notebook->idle_focus_id);
+
+ G_OBJECT_CLASS (gail_notebook_parent_class)->finalize (object);
+}
+
+static void
+atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ iface->add_selection = gail_notebook_add_selection;
+ iface->ref_selection = gail_notebook_ref_selection;
+ iface->get_selection_count = gail_notebook_get_selection_count;
+ iface->is_child_selected = gail_notebook_is_child_selected;
+ /*
+ * The following don't make any sense for GtkNotebook widgets.
+ * Unsupported AtkSelection interfaces:
+ * clear_selection();
+ * remove_selection();
+ * select_all_selection();
+ */
+}
+
+/*
+ * GtkNotebook only supports the selection of one page at a time.
+ * Selecting a page unselects any previous selection, so this
+ * changes the current selection instead of adding to it.
+ */
+static gboolean
+gail_notebook_add_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkNotebook *notebook;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+ notebook = GTK_NOTEBOOK (widget);
+ gtk_notebook_set_current_page (notebook, i);
+ return TRUE;
+}
+
+static AtkObject*
+gail_notebook_ref_selection (AtkSelection *selection,
+ gint i)
+{
+ AtkObject *accessible;
+ GtkWidget *widget;
+ GtkNotebook *notebook;
+ gint pagenum;
+
+ /*
+ * A note book can have only one selection.
+ */
+ gail_return_val_if_fail (i == 0, NULL);
+ g_return_val_if_fail (GAIL_IS_NOTEBOOK (selection), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ notebook = GTK_NOTEBOOK (widget);
+ pagenum = gtk_notebook_get_current_page (notebook);
+ gail_return_val_if_fail (pagenum != -1, NULL);
+ accessible = gail_notebook_ref_child (ATK_OBJECT (selection), pagenum);
+
+ return accessible;
+}
+
+/*
+ * Always return 1 because there can only be one page
+ * selected at any time
+ */
+static gint
+gail_notebook_get_selection_count (AtkSelection *selection)
+{
+ GtkWidget *widget;
+ GtkNotebook *notebook;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return 0;
+
+ notebook = GTK_NOTEBOOK (widget);
+ if (notebook == NULL || gtk_notebook_get_current_page (notebook) == -1)
+ return 0;
+ else
+ return 1;
+}
+
+static gboolean
+gail_notebook_is_child_selected (AtkSelection *selection,
+ gint i)
+{
+ GtkWidget *widget;
+ GtkNotebook *notebook;
+ gint pagenumber;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+
+
+ notebook = GTK_NOTEBOOK (widget);
+ pagenumber = gtk_notebook_get_current_page(notebook);
+
+ if (pagenumber == i)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static AtkObject*
+find_child_in_list (GList *list,
+ gint index)
+{
+ AtkObject *obj = NULL;
+
+ while (list)
+ {
+ if (GAIL_NOTEBOOK_PAGE (list->data)->index == index)
+ {
+ obj = ATK_OBJECT (list->data);
+ break;
+ }
+ list = list->next;
+ }
+ return obj;
+}
+
+static void
+check_cache (GailNotebook *gail_notebook,
+ GtkNotebook *notebook)
+{
+ GList *gtk_list;
+ GList *gail_list;
+ gint i;
+
+ gtk_list = gtk_container_get_children (GTK_CONTAINER (notebook));
+ gail_list = gail_notebook->page_cache;
+
+ i = 0;
+ while (gtk_list)
+ {
+ if (!gail_list)
+ {
+ create_notebook_page_accessible (gail_notebook, notebook, i, FALSE, NULL);
+ }
+ else if (GAIL_NOTEBOOK_PAGE (gail_list->data)->page != gtk_list->data)
+ {
+ create_notebook_page_accessible (gail_notebook, notebook, i, TRUE, gail_list);
+ }
+ else
+ {
+ gail_list = gail_list->next;
+ }
+ i++;
+ gtk_list = gtk_list->next;
+ }
+ g_list_free (gtk_list);
+
+ gail_notebook->page_count = i;
+}
+
+static void
+reset_cache (GailNotebook *gail_notebook,
+ gint index)
+{
+ GList *l;
+
+ for (l = gail_notebook->page_cache; l; l = l->next)
+ {
+ if (GAIL_NOTEBOOK_PAGE (l->data)->index > index)
+ GAIL_NOTEBOOK_PAGE (l->data)->index -= 1;
+ }
+}
+
+static void
+create_notebook_page_accessible (GailNotebook *gail_notebook,
+ GtkNotebook *notebook,
+ gint index,
+ gboolean insert_before,
+ GList *list)
+{
+ AtkObject *obj;
+
+ obj = gail_notebook_page_new (notebook, index);
+ g_object_ref (obj);
+ if (insert_before)
+ gail_notebook->page_cache = g_list_insert_before (gail_notebook->page_cache, list, obj);
+ else
+ gail_notebook->page_cache = g_list_append (gail_notebook->page_cache, obj);
+ g_signal_connect (gtk_notebook_get_nth_page (notebook, index),
+ "parent_set",
+ G_CALLBACK (gail_notebook_child_parent_set),
+ obj);
+}
+
+static void
+gail_notebook_child_parent_set (GtkWidget *widget,
+ GtkWidget *old_parent,
+ gpointer data)
+{
+ GailNotebook *gail_notebook;
+
+ gail_return_if_fail (old_parent != NULL);
+ gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (old_parent));
+ gail_notebook->remove_index = GAIL_NOTEBOOK_PAGE (data)->index;
+}
+
+static gint
+gail_notebook_real_remove_gtk (GtkContainer *container,
+ GtkWidget *widget,
+ gpointer data)
+{
+ GailNotebook *gail_notebook;
+ AtkObject *obj;
+ gint index;
+
+ g_return_val_if_fail (container != NULL, 1);
+ gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (GTK_WIDGET (container)));
+ index = gail_notebook->remove_index;
+ gail_notebook->remove_index = -1;
+
+ obj = find_child_in_list (gail_notebook->page_cache, index);
+ g_return_val_if_fail (obj, 1);
+ gail_notebook->page_cache = g_list_remove (gail_notebook->page_cache, obj);
+ gail_notebook->page_count -= 1;
+ reset_cache (gail_notebook, index);
+ g_signal_emit_by_name (gail_notebook,
+ "children_changed::remove",
+ GAIL_NOTEBOOK_PAGE (obj)->index,
+ obj, NULL);
+ g_object_unref (obj);
+ return 1;
+}
+
+static gboolean
+gail_notebook_focus_cb (GtkWidget *widget,
+ GtkDirectionType type)
+{
+ AtkObject *atk_obj = gtk_widget_get_accessible (widget);
+ GailNotebook *gail_notebook = GAIL_NOTEBOOK (atk_obj);
+
+ switch (type)
+ {
+ case GTK_DIR_LEFT:
+ case GTK_DIR_RIGHT:
+ if (gail_notebook->idle_focus_id == 0)
+ gail_notebook->idle_focus_id = gdk_threads_add_idle (gail_notebook_check_focus_tab, atk_obj);
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean
+gail_notebook_check_focus_tab (gpointer data)
+{
+ GtkWidget *widget;
+ AtkObject *atk_obj;
+ gint focus_page_num, old_focus_page_num;
+ GailNotebook *gail_notebook;
+ GtkNotebook *gtk_notebook;
+
+ atk_obj = ATK_OBJECT (data);
+ gail_notebook = GAIL_NOTEBOOK (atk_obj);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj));
+
+ gtk_notebook = GTK_NOTEBOOK (widget);
+
+ gail_notebook->idle_focus_id = 0;
+
+ focus_page_num = gtk_notebook_get_current_page (gtk_notebook);
+ if (focus_page_num == -1)
+ return FALSE;
+
+ old_focus_page_num = gail_notebook->focus_tab_page;
+ gail_notebook->focus_tab_page = focus_page_num;
+ if (old_focus_page_num != focus_page_num)
+ {
+ AtkObject *obj;
+
+ obj = atk_object_ref_accessible_child (atk_obj, focus_page_num);
+ atk_focus_tracker_notify (obj);
+ g_object_unref (obj);
+ }
+
+ return FALSE;
+}
+
+static void
+gail_notebook_destroyed (gpointer data)
+{
+ GailNotebook *gail_notebook = GAIL_NOTEBOOK (data);
+
+ if (gail_notebook->idle_focus_id)
+ {
+ g_source_remove (gail_notebook->idle_focus_id);
+ gail_notebook->idle_focus_id = 0;
+ }
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_NOTEBOOK_H__
+#define __GAIL_NOTEBOOK_H__
+
+#include "gailcontainer.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_NOTEBOOK (gail_notebook_get_type ())
+#define GAIL_NOTEBOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_NOTEBOOK, GailNotebook))
+#define GAIL_NOTEBOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_NOTEBOOK, GailNotebookClass))
+#define GAIL_IS_NOTEBOOK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_NOTEBOOK))
+#define GAIL_IS_NOTEBOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_NOTEBOOK))
+#define GAIL_NOTEBOOK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_NOTEBOOK, GailNotebookClass))
+
+typedef struct _GailNotebook GailNotebook;
+typedef struct _GailNotebookClass GailNotebookClass;
+
+struct _GailNotebook
+{
+ GailContainer parent;
+
+ /*
+ * page_cache maintains a list of pre-ref'd Notebook Pages.
+ * This cache is queried by gail_notebook_ref_child().
+ * If the page is found in the list then a new page does not
+ * need to be created
+ */
+ GList* page_cache;
+ gint selected_page;
+ gint focus_tab_page;
+ gint page_count;
+ guint idle_focus_id;
+
+ gint remove_index;
+};
+
+GType gail_notebook_get_type (void);
+
+struct _GailNotebookClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_NOTEBOOK_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailnotebookpage.h"
+#include <libgail-util/gailmisc.h>
+#include "gail-private-macros.h"
+
+static void gail_notebook_page_class_init (GailNotebookPageClass *klass);
+static void gail_notebook_page_init (GailNotebookPage *page);
+static void gail_notebook_page_finalize (GObject *object);
+static void gail_notebook_page_label_map_gtk (GtkWidget *widget,
+ gpointer data);
+
+static const gchar* gail_notebook_page_get_name (AtkObject *accessible);
+static AtkObject* gail_notebook_page_get_parent (AtkObject *accessible);
+static gint gail_notebook_page_get_n_children (AtkObject *accessible);
+static AtkObject* gail_notebook_page_ref_child (AtkObject *accessible,
+ gint i);
+static gint gail_notebook_page_get_index_in_parent
+ (AtkObject *accessible);
+static AtkStateSet* gail_notebook_page_ref_state_set (AtkObject *accessible);
+
+static gint gail_notebook_page_notify (GObject *obj,
+ GParamSpec *pspec,
+ gpointer user_data);
+static void gail_notebook_page_init_textutil (GailNotebookPage *notebook_page,
+ GtkWidget *label);
+
+static void atk_component_interface_init (AtkComponentIface *iface);
+
+static AtkObject* gail_notebook_page_ref_accessible_at_point
+ (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type);
+
+static void gail_notebook_page_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+
+static AtkObject* _gail_notebook_page_get_tab_label (GailNotebookPage *page);
+
+/* atktext.h */
+static void atk_text_interface_init (AtkTextIface *iface);
+
+static gchar* gail_notebook_page_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gunichar gail_notebook_page_get_character_at_offset
+ (AtkText *text,
+ gint offset);
+static gchar* gail_notebook_page_get_text_before_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_notebook_page_get_text_at_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_notebook_page_get_text_after_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gint gail_notebook_page_get_character_count (AtkText *text);
+static void gail_notebook_page_get_character_extents
+ (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static gint gail_notebook_page_get_offset_at_point
+ (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static AtkAttributeSet* gail_notebook_page_get_run_attributes
+ (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet* gail_notebook_page_get_default_attributes
+ (AtkText *text);
+static GtkWidget* get_label_from_notebook_page (GailNotebookPage *page);
+static GtkWidget* find_label_child (GtkContainer *container);
+
+/* FIXME: not GAIL_TYPE_OBJECT? */
+G_DEFINE_TYPE_WITH_CODE (GailNotebookPage, gail_notebook_page, ATK_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
+
+static void
+gail_notebook_page_class_init (GailNotebookPageClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->get_name = gail_notebook_page_get_name;
+ class->get_parent = gail_notebook_page_get_parent;
+ class->get_n_children = gail_notebook_page_get_n_children;
+ class->ref_child = gail_notebook_page_ref_child;
+ class->ref_state_set = gail_notebook_page_ref_state_set;
+ class->get_index_in_parent = gail_notebook_page_get_index_in_parent;
+
+ gobject_class->finalize = gail_notebook_page_finalize;
+}
+
+static void
+gail_notebook_page_init (GailNotebookPage *page)
+{
+}
+
+static gint
+notify_child_added (gpointer data)
+{
+ GailNotebookPage *page;
+ AtkObject *atk_object, *atk_parent;
+
+ g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (data), FALSE);
+ page = GAIL_NOTEBOOK_PAGE (data);
+ atk_object = ATK_OBJECT (data);
+
+ page->notify_child_added_id = 0;
+
+ /* The widget page->notebook may be deleted before this handler is called */
+ if (page->notebook != NULL)
+ {
+ atk_parent = gtk_widget_get_accessible (GTK_WIDGET (page->notebook));
+ atk_object_set_parent (atk_object, atk_parent);
+ g_signal_emit_by_name (atk_parent, "children_changed::add", page->index, atk_object, NULL);
+ }
+
+ return FALSE;
+}
+
+AtkObject*
+gail_notebook_page_new (GtkNotebook *notebook,
+ gint pagenum)
+{
+ GObject *object;
+ AtkObject *atk_object;
+ GailNotebookPage *page;
+ GtkWidget *child;
+ GtkWidget *label;
+ GtkWidget *widget_page;
+
+ g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
+
+ child = gtk_notebook_get_nth_page (notebook, pagenum);
+
+ if (!child)
+ return NULL;
+
+ object = g_object_new (GAIL_TYPE_NOTEBOOK_PAGE, NULL);
+ g_return_val_if_fail (object != NULL, NULL);
+
+ page = GAIL_NOTEBOOK_PAGE (object);
+ page->notebook = notebook;
+ g_object_add_weak_pointer (G_OBJECT (page->notebook), (gpointer *)&page->notebook);
+ page->index = pagenum;
+ widget_page = gtk_notebook_get_nth_page (notebook, pagenum);
+ page->page = widget_page;
+ page->textutil = NULL;
+
+ atk_object = ATK_OBJECT (page);
+ atk_object->role = ATK_ROLE_PAGE_TAB;
+ atk_object->layer = ATK_LAYER_WIDGET;
+
+ page->notify_child_added_id = gdk_threads_add_idle (notify_child_added, atk_object);
+ /*
+ * We get notified of changes to the label
+ */
+ label = get_label_from_notebook_page (page);
+ if (GTK_IS_LABEL (label))
+ {
+ if (gtk_widget_get_mapped (label))
+ gail_notebook_page_init_textutil (page, label);
+ else
+ g_signal_connect (label,
+ "map",
+ G_CALLBACK (gail_notebook_page_label_map_gtk),
+ page);
+ }
+
+ return atk_object;
+}
+
+static void
+gail_notebook_page_label_map_gtk (GtkWidget *widget,
+ gpointer data)
+{
+ GailNotebookPage *page;
+
+ page = GAIL_NOTEBOOK_PAGE (data);
+ gail_notebook_page_init_textutil (page, widget);
+}
+
+static void
+gail_notebook_page_init_textutil (GailNotebookPage *page,
+ GtkWidget *label)
+{
+ const gchar *label_text;
+
+ if (page->textutil == NULL)
+ {
+ page->textutil = gail_text_util_new ();
+ g_signal_connect (label,
+ "notify",
+ (GCallback) gail_notebook_page_notify,
+ page);
+ }
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ gail_text_util_text_setup (page->textutil, label_text);
+}
+
+static gint
+gail_notebook_page_notify (GObject *obj,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ AtkObject *atk_obj = ATK_OBJECT (user_data);
+ GtkLabel *label;
+ GailNotebookPage *page;
+
+ if (strcmp (pspec->name, "label") == 0)
+ {
+ const gchar* label_text;
+
+ label = GTK_LABEL (obj);
+
+ label_text = gtk_label_get_text (label);
+
+ page = GAIL_NOTEBOOK_PAGE (atk_obj);
+ gail_text_util_text_setup (page->textutil, label_text);
+
+ if (atk_obj->name == NULL)
+ {
+ /*
+ * The label has changed so notify a change in accessible-name
+ */
+ g_object_notify (G_OBJECT (atk_obj), "accessible-name");
+ }
+ /*
+ * The label is the only property which can be changed
+ */
+ g_signal_emit_by_name (atk_obj, "visible_data_changed");
+ }
+ return 1;
+}
+
+static void
+gail_notebook_page_finalize (GObject *object)
+{
+ GailNotebookPage *page = GAIL_NOTEBOOK_PAGE (object);
+
+ if (page->notebook)
+ g_object_remove_weak_pointer (G_OBJECT (page->notebook), (gpointer *)&page->notebook);
+
+ if (page->textutil)
+ g_object_unref (page->textutil);
+
+ if (page->notify_child_added_id)
+ g_source_remove (page->notify_child_added_id);
+
+ G_OBJECT_CLASS (gail_notebook_page_parent_class)->finalize (object);
+}
+
+static const gchar*
+gail_notebook_page_get_name (AtkObject *accessible)
+{
+ g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), NULL);
+
+ if (accessible->name != NULL)
+ return accessible->name;
+ else
+ {
+ GtkWidget *label;
+
+ label = get_label_from_notebook_page (GAIL_NOTEBOOK_PAGE (accessible));
+ if (GTK_IS_LABEL (label))
+ return gtk_label_get_text (GTK_LABEL (label));
+ else
+ return NULL;
+ }
+}
+
+static AtkObject*
+gail_notebook_page_get_parent (AtkObject *accessible)
+{
+ GailNotebookPage *page;
+
+ g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), NULL);
+
+ page = GAIL_NOTEBOOK_PAGE (accessible);
+
+ if (!page->notebook)
+ return NULL;
+
+ return gtk_widget_get_accessible (GTK_WIDGET (page->notebook));
+}
+
+static gint
+gail_notebook_page_get_n_children (AtkObject *accessible)
+{
+ /* Notebook page has only one child */
+ g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), 0);
+
+ return 1;
+}
+
+static AtkObject*
+gail_notebook_page_ref_child (AtkObject *accessible,
+ gint i)
+{
+ GtkWidget *child;
+ AtkObject *child_obj;
+ GailNotebookPage *page = NULL;
+
+ g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), NULL);
+ if (i != 0)
+ return NULL;
+
+ page = GAIL_NOTEBOOK_PAGE (accessible);
+ if (!page->notebook)
+ return NULL;
+
+ child = gtk_notebook_get_nth_page (page->notebook, page->index);
+ gail_return_val_if_fail (GTK_IS_WIDGET (child), NULL);
+
+ child_obj = gtk_widget_get_accessible (child);
+ g_object_ref (child_obj);
+ return child_obj;
+}
+
+static gint
+gail_notebook_page_get_index_in_parent (AtkObject *accessible)
+{
+ GailNotebookPage *page;
+
+ g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), -1);
+ page = GAIL_NOTEBOOK_PAGE (accessible);
+
+ return page->index;
+}
+
+static AtkStateSet*
+gail_notebook_page_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set, *label_state_set, *merged_state_set;
+ AtkObject *atk_label;
+
+ g_return_val_if_fail (GAIL_NOTEBOOK_PAGE (accessible), NULL);
+
+ state_set = ATK_OBJECT_CLASS (gail_notebook_page_parent_class)->ref_state_set (accessible);
+
+ atk_label = _gail_notebook_page_get_tab_label (GAIL_NOTEBOOK_PAGE (accessible));
+ if (atk_label)
+ {
+ label_state_set = atk_object_ref_state_set (atk_label);
+ merged_state_set = atk_state_set_or_sets (state_set, label_state_set);
+ g_object_unref (label_state_set);
+ g_object_unref (state_set);
+ }
+ else
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (accessible, 0);
+ gail_return_val_if_fail (child, state_set);
+
+ merged_state_set = state_set;
+ state_set = atk_object_ref_state_set (child);
+ if (atk_state_set_contains_state (state_set, ATK_STATE_VISIBLE))
+ {
+ atk_state_set_add_state (merged_state_set, ATK_STATE_VISIBLE);
+ if (atk_state_set_contains_state (state_set, ATK_STATE_ENABLED))
+ atk_state_set_add_state (merged_state_set, ATK_STATE_ENABLED);
+ if (atk_state_set_contains_state (state_set, ATK_STATE_SHOWING))
+ atk_state_set_add_state (merged_state_set, ATK_STATE_SHOWING);
+
+ }
+ g_object_unref (state_set);
+ g_object_unref (child);
+ }
+ return merged_state_set;
+}
+
+
+static void
+atk_component_interface_init (AtkComponentIface *iface)
+{
+ /*
+ * We use the default implementations for contains, get_position, get_size
+ */
+ iface->ref_accessible_at_point = gail_notebook_page_ref_accessible_at_point;
+ iface->get_extents = gail_notebook_page_get_extents;
+}
+
+static AtkObject*
+gail_notebook_page_ref_accessible_at_point (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type)
+{
+ /*
+ * There is only one child so we return it.
+ */
+ AtkObject* child;
+
+ g_return_val_if_fail (ATK_IS_OBJECT (component), NULL);
+
+ child = atk_object_ref_accessible_child (ATK_OBJECT (component), 0);
+ return child;
+}
+
+static void
+gail_notebook_page_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ AtkObject *atk_label;
+
+ g_return_if_fail (GAIL_IS_NOTEBOOK_PAGE (component));
+
+ atk_label = _gail_notebook_page_get_tab_label (GAIL_NOTEBOOK_PAGE (component));
+
+ if (!atk_label)
+ {
+ AtkObject *child;
+
+ *width = 0;
+ *height = 0;
+
+ child = atk_object_ref_accessible_child (ATK_OBJECT (component), 0);
+ gail_return_if_fail (child);
+
+ atk_component_get_position (ATK_COMPONENT (child), x, y, coord_type);
+ g_object_unref (child);
+ }
+ else
+ {
+ atk_component_get_extents (ATK_COMPONENT (atk_label),
+ x, y, width, height, coord_type);
+ }
+ return;
+}
+
+static AtkObject*
+_gail_notebook_page_get_tab_label (GailNotebookPage *page)
+{
+ GtkWidget *label;
+
+ label = get_label_from_notebook_page (page);
+ if (label)
+ return gtk_widget_get_accessible (label);
+ else
+ return NULL;
+}
+
+/* atktext.h */
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_notebook_page_get_text;
+ iface->get_character_at_offset = gail_notebook_page_get_character_at_offset;
+ iface->get_text_before_offset = gail_notebook_page_get_text_before_offset;
+ iface->get_text_at_offset = gail_notebook_page_get_text_at_offset;
+ iface->get_text_after_offset = gail_notebook_page_get_text_after_offset;
+ iface->get_character_count = gail_notebook_page_get_character_count;
+ iface->get_character_extents = gail_notebook_page_get_character_extents;
+ iface->get_offset_at_point = gail_notebook_page_get_offset_at_point;
+ iface->get_run_attributes = gail_notebook_page_get_run_attributes;
+ iface->get_default_attributes = gail_notebook_page_get_default_attributes;
+}
+
+static gchar*
+gail_notebook_page_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+ const gchar *label_text;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL (label))
+ return NULL;
+
+ if (!notebook_page->textutil)
+ gail_notebook_page_init_textutil (notebook_page, label);
+
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+
+ if (label_text == NULL)
+ return NULL;
+ else
+ {
+ return gail_text_util_get_substring (notebook_page->textutil,
+ start_pos, end_pos);
+ }
+}
+
+static gchar*
+gail_notebook_page_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ if (!notebook_page->textutil)
+ gail_notebook_page_init_textutil (notebook_page, label);
+
+ return gail_text_util_get_text (notebook_page->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)), GAIL_BEFORE_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_notebook_page_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ if (!notebook_page->textutil)
+ gail_notebook_page_init_textutil (notebook_page, label);
+
+ return gail_text_util_get_text (notebook_page->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)), GAIL_AT_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_notebook_page_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ if (!notebook_page->textutil)
+ gail_notebook_page_init_textutil (notebook_page, label);
+
+ return gail_text_util_get_text (notebook_page->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gint
+gail_notebook_page_get_character_count (AtkText *text)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL(label))
+ return 0;
+
+ return g_utf8_strlen (gtk_label_get_text (GTK_LABEL (label)), -1);
+}
+
+static void
+gail_notebook_page_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+ PangoRectangle char_rect;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL(label))
+ return;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
+ pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
+
+ gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
+ x_layout, y_layout, x, y, width, height, coords);
+}
+
+static gint
+gail_notebook_page_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL(label))
+ return -1;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+
+ index = gail_misc_get_index_at_point_in_layout (label,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ x_layout, y_layout, x, y, coords);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ if (index == -1)
+ {
+ if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
+ return g_utf8_strlen (label_text, -1);
+
+ return index;
+ }
+ else
+ return g_utf8_pointer_to_offset (label_text, label_text + index);
+}
+
+static AtkAttributeSet*
+gail_notebook_page_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+ AtkAttributeSet *at_set = NULL;
+ GtkJustification justify;
+ GtkTextDirection dir;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ /* Get values set for entire label, if any */
+ justify = gtk_label_get_justify (GTK_LABEL (label));
+ if (justify != GTK_JUSTIFY_CENTER)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_JUSTIFICATION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
+ }
+ dir = gtk_widget_get_direction (label);
+ if (dir == GTK_TEXT_DIR_RTL)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_DIRECTION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
+ }
+
+ at_set = gail_misc_layout_get_run_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ (gchar *) gtk_label_get_text (GTK_LABEL (label)),
+ offset,
+ start_offset,
+ end_offset);
+ return at_set;
+}
+
+static AtkAttributeSet*
+gail_notebook_page_get_default_attributes (AtkText *text)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+ AtkAttributeSet *at_set = NULL;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ at_set = gail_misc_get_default_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ label);
+ return at_set;
+}
+
+static gunichar
+gail_notebook_page_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GtkWidget *label;
+ GailNotebookPage *notebook_page;
+ const gchar *string;
+ gchar *index;
+
+ notebook_page = GAIL_NOTEBOOK_PAGE (text);
+ label = get_label_from_notebook_page (notebook_page);
+
+ if (!GTK_IS_LABEL(label))
+ return '\0';
+ string = gtk_label_get_text (GTK_LABEL (label));
+ if (offset >= g_utf8_strlen (string, -1))
+ return '\0';
+ index = g_utf8_offset_to_pointer (string, offset);
+
+ return g_utf8_get_char (index);
+}
+
+static GtkWidget*
+get_label_from_notebook_page (GailNotebookPage *page)
+{
+ GtkWidget *child;
+ GtkNotebook *notebook;
+
+ notebook = page->notebook;
+ if (!notebook)
+ return NULL;
+
+ if (!gtk_notebook_get_show_tabs (notebook))
+ return NULL;
+
+ child = gtk_notebook_get_nth_page (notebook, page->index);
+ if (child == NULL) return NULL;
+ g_return_val_if_fail (GTK_IS_WIDGET (child), NULL);
+
+ child = gtk_notebook_get_tab_label (notebook, child);
+
+ if (GTK_IS_LABEL (child))
+ return child;
+
+ if (GTK_IS_CONTAINER (child))
+ child = find_label_child (GTK_CONTAINER (child));
+
+ return child;
+}
+
+static GtkWidget*
+find_label_child (GtkContainer *container)
+{
+ GList *children, *tmp_list;
+ GtkWidget *child;
+
+ children = gtk_container_get_children (container);
+
+ child = NULL;
+ for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
+ {
+ if (GTK_IS_LABEL (tmp_list->data))
+ {
+ child = GTK_WIDGET (tmp_list->data);
+ break;
+ }
+ else if (GTK_IS_CONTAINER (tmp_list->data))
+ {
+ child = find_label_child (GTK_CONTAINER (tmp_list->data));
+ if (child)
+ break;
+ }
+ }
+ g_list_free (children);
+ return child;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_NOTEBOOK_PAGE_H__
+#define __GAIL_NOTEBOOK_PAGE_H__
+
+#include "gailnotebook.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_NOTEBOOK_PAGE (gail_notebook_page_get_type ())
+#define GAIL_NOTEBOOK_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),GAIL_TYPE_NOTEBOOK_PAGE, GailNotebookPage))
+#define GAIL_NOTEBOOK_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_NOTEBOOK_PAGE, GailNotebookPageClass))
+#define GAIL_IS_NOTEBOOK_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_NOTEBOOK_PAGE))
+#define GAIL_IS_NOTEBOOK_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_NOTEBOOK_PAGE))
+#define GAIL_NOTEBOOK_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_NOTEBOOK_PAGE, GailNotebookPageClass))
+
+typedef struct _GailNotebookPage GailNotebookPage;
+typedef struct _GailNotebookPageClass GailNotebookPageClass;
+
+struct _GailNotebookPage
+{
+ AtkObject parent;
+
+ GtkNotebook *notebook;
+#ifndef GTK_DISABLE_DEPRECATED
+ GtkNotebookPage *page;
+#else
+ gpointer page;
+#endif
+
+ gint index;
+ guint notify_child_added_id;
+
+ GailTextUtil *textutil;
+};
+
+GType gail_notebook_page_get_type (void);
+
+struct _GailNotebookPageClass
+{
+ AtkObjectClass parent_class;
+};
+
+AtkObject *gail_notebook_page_new(GtkNotebook *notebook, gint pagenum);
+
+G_END_DECLS
+
+#endif /* __GAIL_NOTEBOOK_PAGE_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailpaned.h"
+
+static void gail_paned_class_init (GailPanedClass *klass);
+
+static void gail_paned_init (GailPaned *paned);
+
+static void gail_paned_real_initialize (AtkObject *obj,
+ gpointer data);
+static void gail_paned_size_allocate_gtk (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void atk_value_interface_init (AtkValueIface *iface);
+static void gail_paned_get_current_value (AtkValue *obj,
+ GValue *value);
+static void gail_paned_get_maximum_value (AtkValue *obj,
+ GValue *value);
+static void gail_paned_get_minimum_value (AtkValue *obj,
+ GValue *value);
+static gboolean gail_paned_set_current_value (AtkValue *obj,
+ const GValue *value);
+
+G_DEFINE_TYPE_WITH_CODE (GailPaned, gail_paned, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
+
+static void
+gail_paned_class_init (GailPanedClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->initialize = gail_paned_real_initialize;
+}
+
+static void
+gail_paned_init (GailPaned *paned)
+{
+}
+
+static void
+gail_paned_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_paned_parent_class)->initialize (obj, data);
+
+ g_signal_connect (data,
+ "size_allocate",
+ G_CALLBACK (gail_paned_size_allocate_gtk),
+ NULL);
+
+ obj->role = ATK_ROLE_SPLIT_PANE;
+}
+
+static void
+gail_paned_size_allocate_gtk (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ AtkObject *obj = gtk_widget_get_accessible (widget);
+
+ g_object_notify (G_OBJECT (obj), "accessible-value");
+}
+
+
+static void
+atk_value_interface_init (AtkValueIface *iface)
+{
+ iface->get_current_value = gail_paned_get_current_value;
+ iface->get_maximum_value = gail_paned_get_maximum_value;
+ iface->get_minimum_value = gail_paned_get_minimum_value;
+ iface->set_current_value = gail_paned_set_current_value;
+}
+
+static void
+gail_paned_get_current_value (AtkValue *obj,
+ GValue *value)
+{
+ GtkWidget* widget;
+ gint current_value;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ current_value = gtk_paned_get_position (GTK_PANED (widget));
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value,current_value);
+}
+
+static void
+gail_paned_get_maximum_value (AtkValue *obj,
+ GValue *value)
+{
+ GtkWidget* widget;
+ gint maximum_value;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ g_object_get (GTK_PANED (widget),
+ "max-position", &maximum_value,
+ NULL);
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, maximum_value);
+}
+
+static void
+gail_paned_get_minimum_value (AtkValue *obj,
+ GValue *value)
+{
+ GtkWidget* widget;
+ gint minimum_value;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ g_object_get (GTK_PANED (widget),
+ "min-position", &minimum_value,
+ NULL);
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, minimum_value);
+}
+
+/*
+ * Calling atk_value_set_current_value() is no guarantee that the value is
+ * acceptable; it is necessary to listen for accessible-value signals
+ * and check whether the current value has been changed or check what the
+ * maximum and minimum values are.
+ */
+
+static gboolean
+gail_paned_set_current_value (AtkValue *obj,
+ const GValue *value)
+{
+ GtkWidget* widget;
+ gint new_value;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ if (G_VALUE_HOLDS_INT (value))
+ {
+ new_value = g_value_get_int (value);
+ gtk_paned_set_position (GTK_PANED (widget), new_value);
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_PANED_H__
+#define __GAIL_PANED_H__
+
+#include "gailcontainer.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_PANED (gail_paned_get_type ())
+#define GAIL_PANED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_PANED, GailPaned))
+#define GAIL_PANED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_PANED, GailPanedClass))
+#define GAIL_IS_PANED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_PANED))
+#define GAIL_IS_PANED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_PANED))
+#define GAIL_PANED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_PANED, GailPanedClass))
+
+typedef struct _GailPaned GailPaned;
+typedef struct _GailPanedClass GailPanedClass;
+
+struct _GailPaned
+{
+ GailContainer parent;
+};
+
+GType gail_paned_get_type (void);
+
+struct _GailPanedClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_PANED_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include "gailprogressbar.h"
+#include "gailadjustment.h"
+
+static void gail_progress_bar_class_init (GailProgressBarClass *klass);
+static void gail_progress_bar_init (GailProgressBar *bar);
+static void gail_progress_bar_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static void atk_value_interface_init (AtkValueIface *iface);
+
+
+static void gail_progress_bar_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+
+static void gail_progress_bar_get_current_value (AtkValue *obj,
+ GValue *value);
+static void gail_progress_bar_get_maximum_value (AtkValue *obj,
+ GValue *value);
+static void gail_progress_bar_get_minimum_value (AtkValue *obj,
+ GValue *value);
+
+G_DEFINE_TYPE_WITH_CODE (GailProgressBar, gail_progress_bar, GAIL_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
+
+static void
+gail_progress_bar_class_init (GailProgressBarClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailWidgetClass *widget_class;
+
+ widget_class = (GailWidgetClass*)klass;
+
+ widget_class->notify_gtk = gail_progress_bar_real_notify_gtk;
+
+ class->initialize = gail_progress_bar_real_initialize;
+}
+
+static void
+gail_progress_bar_init (GailProgressBar *bar)
+{
+}
+
+static void
+gail_progress_bar_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_progress_bar_parent_class)->initialize (obj, data);
+
+ obj->role = ATK_ROLE_PROGRESS_BAR;
+}
+
+static void
+atk_value_interface_init (AtkValueIface *iface)
+{
+ iface->get_current_value = gail_progress_bar_get_current_value;
+ iface->get_maximum_value = gail_progress_bar_get_maximum_value;
+ iface->get_minimum_value = gail_progress_bar_get_minimum_value;
+}
+
+static void
+gail_progress_bar_get_current_value (AtkValue *obj,
+ GValue *value)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (GAIL_IS_PROGRESS_BAR (obj));
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (widget)));
+}
+
+static void
+gail_progress_bar_get_maximum_value (AtkValue *obj,
+ GValue *value)
+{
+ g_return_if_fail (GAIL_IS_PROGRESS_BAR (obj));
+
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, 1.0);
+}
+
+static void
+gail_progress_bar_get_minimum_value (AtkValue *obj,
+ GValue *value)
+{
+ g_return_if_fail (GAIL_IS_PROGRESS_BAR (obj));
+
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, 0.0);
+}
+
+static void
+gail_progress_bar_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkWidget *widget = GTK_WIDGET (obj);
+ GailProgressBar *progress_bar = GAIL_PROGRESS_BAR (gtk_widget_get_accessible (widget));
+
+ if (strcmp (pspec->name, "fraction") == 0)
+ g_object_notify (G_OBJECT (progress_bar), "accessible-value");
+ else
+ GAIL_WIDGET_CLASS (gail_progress_bar_parent_class)->notify_gtk (obj, pspec);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_PROGRESS_BAR_H__
+#define __GAIL_PROGRESS_BAR_H__
+
+#include "gailwidget.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_PROGRESS_BAR (gail_progress_bar_get_type ())
+#define GAIL_PROGRESS_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_PROGRESS_BAR, GailProgressBar))
+#define GAIL_PROGRESS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_PROGRESS_BAR, GailProgressBarClass))
+#define GAIL_IS_PROGRESS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_PROGRESS_BAR))
+#define GAIL_IS_PROGRESS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_PROGRESS_BAR))
+#define GAIL_PROGRESS_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_PROGRESS_BAR, GailProgressBarClass))
+
+typedef struct _GailProgressBar GailProgressBar;
+typedef struct _GailProgressBarClass GailProgressBarClass;
+
+struct _GailProgressBar
+{
+ GailWidget parent;
+};
+
+GType gail_progress_bar_get_type (void);
+
+struct _GailProgressBarClass
+{
+ GailWidgetClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_PROGRESS_BAR_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailradiobutton.h"
+
+static void gail_radio_button_class_init (GailRadioButtonClass *klass);
+static void gail_radio_button_init (GailRadioButton *radio_button);
+static void gail_radio_button_initialize (AtkObject *accessible,
+ gpointer data);
+
+static AtkRelationSet* gail_radio_button_ref_relation_set (AtkObject *obj);
+
+G_DEFINE_TYPE (GailRadioButton, gail_radio_button, GAIL_TYPE_TOGGLE_BUTTON)
+
+static void
+gail_radio_button_class_init (GailRadioButtonClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->initialize = gail_radio_button_initialize;
+ class->ref_relation_set = gail_radio_button_ref_relation_set;
+}
+
+static void
+gail_radio_button_init (GailRadioButton *radio_button)
+{
+ radio_button->old_group = NULL;
+}
+
+static void
+gail_radio_button_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_radio_button_parent_class)->initialize (accessible, data);
+
+ accessible->role = ATK_ROLE_RADIO_BUTTON;
+}
+
+AtkRelationSet*
+gail_radio_button_ref_relation_set (AtkObject *obj)
+{
+ GtkWidget *widget;
+ AtkRelationSet *relation_set;
+ GSList *list;
+ GailRadioButton *radio_button;
+
+ g_return_val_if_fail (GAIL_IS_RADIO_BUTTON (obj), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ {
+ /*
+ * State is defunct
+ */
+ return NULL;
+ }
+ radio_button = GAIL_RADIO_BUTTON (obj);
+
+ relation_set = ATK_OBJECT_CLASS (gail_radio_button_parent_class)->ref_relation_set (obj);
+
+ /*
+ * If the radio button'group has changed remove the relation
+ */
+ list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+
+ if (radio_button->old_group != list)
+ {
+ AtkRelation *relation;
+
+ relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_MEMBER_OF);
+ atk_relation_set_remove (relation_set, relation);
+ }
+
+ if (!atk_relation_set_contains (relation_set, ATK_RELATION_MEMBER_OF))
+ {
+ /*
+ * Get the members of the button group
+ */
+
+ radio_button->old_group = list;
+ if (list)
+ {
+ AtkObject **accessible_array;
+ guint list_length;
+ AtkRelation* relation;
+ gint i = 0;
+
+ list_length = g_slist_length (list);
+ accessible_array = (AtkObject**) g_malloc (sizeof (AtkObject *) *
+ list_length);
+ while (list != NULL)
+ {
+ GtkWidget* list_item = list->data;
+
+ accessible_array[i++] = gtk_widget_get_accessible (list_item);
+
+ list = list->next;
+ }
+ relation = atk_relation_new (accessible_array, list_length,
+ ATK_RELATION_MEMBER_OF);
+ g_free (accessible_array);
+
+ atk_relation_set_add (relation_set, relation);
+ /*
+ * Unref the relation so that it is not leaked.
+ */
+ g_object_unref (relation);
+ }
+ }
+ return relation_set;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_RADIO_BUTTON_H__
+#define __GAIL_RADIO_BUTTON_H__
+
+#include "gailtogglebutton.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_RADIO_BUTTON (gail_radio_button_get_type ())
+#define GAIL_RADIO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RADIO_BUTTON, GailRadioButton))
+#define GAIL_RADIO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RADIO_BUTTON, GailRadioButtonClass))
+#define GAIL_IS_RADIO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RADIO_BUTTON))
+#define GAIL_IS_RADIO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RADIO_BUTTON))
+#define GAIL_RADIO_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RADIO_BUTTON, GailRadioButtonClass))
+
+typedef struct _GailRadioButton GailRadioButton;
+typedef struct _GailRadioButtonClass GailRadioButtonClass;
+
+struct _GailRadioButton
+{
+ GailToggleButton parent;
+
+ GSList *old_group;
+};
+
+GType gail_radio_button_get_type (void);
+
+struct _GailRadioButtonClass
+{
+ GailToggleButtonClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_RADIO_BUTTON_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailradiomenuitem.h"
+#include "gailradiosubmenuitem.h"
+
+static void gail_radio_menu_item_class_init (GailRadioMenuItemClass *klass);
+static void gail_radio_menu_item_init (GailRadioMenuItem *radio_menu_item);
+
+static AtkRelationSet* gail_radio_menu_item_ref_relation_set (AtkObject *obj);
+
+G_DEFINE_TYPE (GailRadioMenuItem, gail_radio_menu_item, GAIL_TYPE_CHECK_MENU_ITEM)
+
+static void
+gail_radio_menu_item_class_init (GailRadioMenuItemClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->ref_relation_set = gail_radio_menu_item_ref_relation_set;
+}
+
+AtkObject*
+gail_radio_menu_item_new (GtkWidget *widget)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (GTK_IS_RADIO_MENU_ITEM (widget), NULL);
+
+ if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)))
+ return gail_radio_sub_menu_item_new (widget);
+
+ object = g_object_new (GAIL_TYPE_RADIO_MENU_ITEM, NULL);
+
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, widget);
+
+ accessible->role = ATK_ROLE_RADIO_MENU_ITEM;
+ return accessible;
+}
+
+static void
+gail_radio_menu_item_init (GailRadioMenuItem *radio_menu_item)
+{
+ radio_menu_item->old_group = NULL;
+}
+
+AtkRelationSet*
+gail_radio_menu_item_ref_relation_set (AtkObject *obj)
+{
+ GtkWidget *widget;
+ AtkRelationSet *relation_set;
+ GSList *list;
+ GailRadioMenuItem *radio_menu_item;
+
+ g_return_val_if_fail (GAIL_IS_RADIO_MENU_ITEM (obj), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ {
+ /*
+ * State is defunct
+ */
+ return NULL;
+ }
+ radio_menu_item = GAIL_RADIO_MENU_ITEM (obj);
+
+ relation_set = ATK_OBJECT_CLASS (gail_radio_menu_item_parent_class)->ref_relation_set (obj);
+
+ /*
+ * If the radio menu_item'group has changed remove the relation
+ */
+ list = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget));
+
+ if (radio_menu_item->old_group != list)
+ {
+ AtkRelation *relation;
+
+ relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_MEMBER_OF);
+ atk_relation_set_remove (relation_set, relation);
+ }
+
+ if (!atk_relation_set_contains (relation_set, ATK_RELATION_MEMBER_OF))
+ {
+ /*
+ * Get the members of the menu_item group
+ */
+
+ radio_menu_item->old_group = list;
+ if (list)
+ {
+ AtkObject **accessible_array;
+ guint list_length;
+ AtkRelation* relation;
+ gint i = 0;
+
+ list_length = g_slist_length (list);
+ accessible_array = (AtkObject**) g_malloc (sizeof (AtkObject *) *
+ list_length);
+ while (list != NULL)
+ {
+ GtkWidget* list_item = list->data;
+
+ accessible_array[i++] = gtk_widget_get_accessible (list_item);
+
+ list = list->next;
+ }
+ relation = atk_relation_new (accessible_array, list_length,
+ ATK_RELATION_MEMBER_OF);
+ g_free (accessible_array);
+
+ atk_relation_set_add (relation_set, relation);
+ /*
+ * Unref the relation so that it is not leaked.
+ */
+ g_object_unref (relation);
+ }
+ }
+ return relation_set;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_RADIO_MENU_ITEM_H__
+#define __GAIL_RADIO_MENU_ITEM_H__
+
+#include "gailcheckmenuitem.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_RADIO_MENU_ITEM (gail_radio_menu_item_get_type ())
+#define GAIL_RADIO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RADIO_MENU_ITEM, GailRadioMenuItem))
+#define GAIL_RADIO_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RADIO_MENU_ITEM, GailRadioMenuItemClass))
+#define GAIL_IS_RADIO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RADIO_MENU_ITEM))
+#define GAIL_IS_RADIO_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RADIO_MENU_ITEM))
+#define GAIL_RADIO_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RADIO_MENU_ITEM, GailRadioMenuItemClass))
+
+typedef struct _GailRadioMenuItem GailRadioMenuItem;
+typedef struct _GailRadioMenuItemClass GailRadioMenuItemClass;
+
+struct _GailRadioMenuItem
+{
+ GailCheckMenuItem parent;
+
+ GSList *old_group;
+};
+
+GType gail_radio_menu_item_get_type (void);
+
+struct _GailRadioMenuItemClass
+{
+ GailCheckMenuItemClass parent_class;
+};
+
+AtkObject* gail_radio_menu_item_new (GtkWidget *widget);
+
+G_END_DECLS
+
+#endif /* __GAIL_RADIO_MENU_ITEM_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailradiosubmenuitem.h"
+
+static void gail_radio_sub_menu_item_class_init (GailRadioSubMenuItemClass *klass);
+static void gail_radio_sub_menu_item_init (GailRadioSubMenuItem *radio_menu_item);
+
+static AtkRelationSet* gail_radio_sub_menu_item_ref_relation_set (AtkObject *obj);
+
+G_DEFINE_TYPE (GailRadioSubMenuItem, gail_radio_sub_menu_item, GAIL_TYPE_CHECK_SUB_MENU_ITEM)
+
+static void
+gail_radio_sub_menu_item_class_init (GailRadioSubMenuItemClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->ref_relation_set = gail_radio_sub_menu_item_ref_relation_set;
+}
+
+AtkObject*
+gail_radio_sub_menu_item_new (GtkWidget *widget)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (GTK_IS_RADIO_MENU_ITEM (widget), NULL);
+
+ object = g_object_new (GAIL_TYPE_RADIO_SUB_MENU_ITEM, NULL);
+
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, widget);
+
+ accessible->role = ATK_ROLE_RADIO_MENU_ITEM;
+ return accessible;
+}
+
+static void
+gail_radio_sub_menu_item_init (GailRadioSubMenuItem *radio_menu_item)
+{
+ radio_menu_item->old_group = NULL;
+}
+
+AtkRelationSet*
+gail_radio_sub_menu_item_ref_relation_set (AtkObject *obj)
+{
+ GtkWidget *widget;
+ AtkRelationSet *relation_set;
+ GSList *list;
+ GailRadioSubMenuItem *radio_menu_item;
+
+ g_return_val_if_fail (GAIL_IS_RADIO_SUB_MENU_ITEM (obj), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ {
+ /*
+ * State is defunct
+ */
+ return NULL;
+ }
+ radio_menu_item = GAIL_RADIO_SUB_MENU_ITEM (obj);
+
+ relation_set = ATK_OBJECT_CLASS (gail_radio_sub_menu_item_parent_class)->ref_relation_set (obj);
+
+ /*
+ * If the radio menu_item'group has changed remove the relation
+ */
+ list = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget));
+
+ if (radio_menu_item->old_group != list)
+ {
+ AtkRelation *relation;
+
+ relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_MEMBER_OF);
+ atk_relation_set_remove (relation_set, relation);
+ }
+
+ if (!atk_relation_set_contains (relation_set, ATK_RELATION_MEMBER_OF))
+ {
+ /*
+ * Get the members of the menu_item group
+ */
+
+ radio_menu_item->old_group = list;
+ if (list)
+ {
+ AtkObject **accessible_array;
+ guint list_length;
+ AtkRelation* relation;
+ gint i = 0;
+
+ list_length = g_slist_length (list);
+ accessible_array = (AtkObject**) g_malloc (sizeof (AtkObject *) *
+ list_length);
+ while (list != NULL)
+ {
+ GtkWidget* list_item = list->data;
+
+ accessible_array[i++] = gtk_widget_get_accessible (list_item);
+
+ list = list->next;
+ }
+ relation = atk_relation_new (accessible_array, list_length,
+ ATK_RELATION_MEMBER_OF);
+ g_free (accessible_array);
+
+ atk_relation_set_add (relation_set, relation);
+ /*
+ * Unref the relation so that it is not leaked.
+ */
+ g_object_unref (relation);
+ }
+ }
+ return relation_set;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_RADIO_SUB_MENU_ITEM_H__
+#define __GAIL_RADIO_SUB_MENU_ITEM_H__
+
+#include "gailchecksubmenuitem.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_RADIO_SUB_MENU_ITEM (gail_radio_sub_menu_item_get_type ())
+#define GAIL_RADIO_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RADIO_SUB_MENU_ITEM, GailRadioSubMenuItem))
+#define GAIL_RADIO_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RADIO_SUB_MENU_ITEM, GailRadioSubMenuItemClass))
+#define GAIL_IS_RADIO_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RADIO_SUB_MENU_ITEM))
+#define GAIL_IS_RADIO_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RADIO_SUB_MENU_ITEM))
+#define GAIL_RADIO_SUB_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RADIO_SUB_MENU_ITEM, GailRadioSubMenuItemClass))
+
+typedef struct _GailRadioSubMenuItem GailRadioSubMenuItem;
+typedef struct _GailRadioSubMenuItemClass GailRadioSubMenuItemClass;
+
+struct _GailRadioSubMenuItem
+{
+ GailCheckSubMenuItem parent;
+
+ GSList *old_group;
+};
+
+GType gail_radio_sub_menu_item_get_type (void);
+
+struct _GailRadioSubMenuItemClass
+{
+ GailCheckSubMenuItemClass parent_class;
+};
+
+AtkObject* gail_radio_sub_menu_item_new (GtkWidget *widget);
+
+G_END_DECLS
+
+#endif /* __GAIL_RADIO_SUB_MENU_ITEM_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "gailrange.h"
+#include "gailadjustment.h"
+#include "gail-private-macros.h"
+
+static void gail_range_class_init (GailRangeClass *klass);
+
+static void gail_range_init (GailRange *range);
+
+static void gail_range_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static void gail_range_finalize (GObject *object);
+
+static void gail_range_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+
+static void atk_value_interface_init (AtkValueIface *iface);
+static void gail_range_get_current_value (AtkValue *obj,
+ GValue *value);
+static void gail_range_get_maximum_value (AtkValue *obj,
+ GValue *value);
+static void gail_range_get_minimum_value (AtkValue *obj,
+ GValue *value);
+static void gail_range_get_minimum_increment (AtkValue *obj,
+ GValue *value);
+static gboolean gail_range_set_current_value (AtkValue *obj,
+ const GValue *value);
+static void gail_range_value_changed (GtkAdjustment *adjustment,
+ gpointer data);
+
+static void atk_action_interface_init (AtkActionIface *iface);
+static gboolean gail_range_do_action (AtkAction *action,
+ gint i);
+static gboolean idle_do_action (gpointer data);
+static gint gail_range_get_n_actions (AtkAction *action);
+static const gchar* gail_range_get_description (AtkAction *action,
+ gint i);
+static const gchar* gail_range_get_keybinding (AtkAction *action,
+ gint i);
+static const gchar* gail_range_action_get_name (AtkAction *action,
+ gint i);
+static gboolean gail_range_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc);
+
+G_DEFINE_TYPE_WITH_CODE (GailRange, gail_range, GAIL_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
+
+static void
+gail_range_class_init (GailRangeClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailWidgetClass *widget_class;
+
+ widget_class = (GailWidgetClass*)klass;
+
+ widget_class->notify_gtk = gail_range_real_notify_gtk;
+
+ class->initialize = gail_range_real_initialize;
+
+ gobject_class->finalize = gail_range_finalize;
+}
+
+static void
+gail_range_init (GailRange *range)
+{
+}
+
+static void
+gail_range_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GailRange *range = GAIL_RANGE (obj);
+ GtkAdjustment *adj;
+ GtkRange *gtk_range;
+
+ ATK_OBJECT_CLASS (gail_range_parent_class)->initialize (obj, data);
+
+ gtk_range = GTK_RANGE (data);
+ /*
+ * If a GtkAdjustment already exists for the GtkRange,
+ * create the GailAdjustment
+ */
+ adj = gtk_range_get_adjustment (gtk_range);
+ if (adj)
+ {
+ range->adjustment = gail_adjustment_new (adj);
+ g_signal_connect (adj,
+ "value-changed",
+ G_CALLBACK (gail_range_value_changed),
+ range);
+ }
+ else
+ range->adjustment = NULL;
+ range->activate_keybinding=NULL;
+ range->activate_description=NULL;
+ /*
+ * Assumed to GtkScale (either GtkHScale or GtkVScale)
+ */
+ obj->role = ATK_ROLE_SLIDER;
+}
+
+static void
+atk_value_interface_init (AtkValueIface *iface)
+{
+ iface->get_current_value = gail_range_get_current_value;
+ iface->get_maximum_value = gail_range_get_maximum_value;
+ iface->get_minimum_value = gail_range_get_minimum_value;
+ iface->get_minimum_increment = gail_range_get_minimum_increment;
+ iface->set_current_value = gail_range_set_current_value;
+}
+
+static void
+gail_range_get_current_value (AtkValue *obj,
+ GValue *value)
+{
+ GailRange *range;
+
+ g_return_if_fail (GAIL_IS_RANGE (obj));
+
+ range = GAIL_RANGE (obj);
+ if (range->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_current_value (ATK_VALUE (range->adjustment), value);
+}
+
+static void
+gail_range_get_maximum_value (AtkValue *obj,
+ GValue *value)
+{
+ GailRange *range;
+ GtkRange *gtk_range;
+ GtkAdjustment *gtk_adjustment;
+ gdouble max = 0;
+
+ g_return_if_fail (GAIL_IS_RANGE (obj));
+
+ range = GAIL_RANGE (obj);
+ if (range->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_maximum_value (ATK_VALUE (range->adjustment), value);
+
+ gtk_range = GTK_RANGE (gtk_accessible_get_widget (GTK_ACCESSIBLE (range)));
+ g_return_if_fail (gtk_range);
+
+ gtk_adjustment = gtk_range_get_adjustment (gtk_range);
+ max = g_value_get_double (value);
+ max -= gtk_adjustment_get_page_size (gtk_adjustment);
+
+ if (gtk_range_get_restrict_to_fill_level (gtk_range))
+ max = MIN (max, gtk_range_get_fill_level (gtk_range));
+
+ g_value_set_double (value, max);
+}
+
+static void
+gail_range_get_minimum_value (AtkValue *obj,
+ GValue *value)
+{
+ GailRange *range;
+
+ g_return_if_fail (GAIL_IS_RANGE (obj));
+
+ range = GAIL_RANGE (obj);
+ if (range->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_minimum_value (ATK_VALUE (range->adjustment), value);
+}
+
+static void
+gail_range_get_minimum_increment (AtkValue *obj, GValue *value)
+{
+ GailRange *range;
+
+ g_return_if_fail (GAIL_IS_RANGE (obj));
+
+ range = GAIL_RANGE (obj);
+ if (range->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_minimum_increment (ATK_VALUE (range->adjustment), value);
+}
+
+static gboolean gail_range_set_current_value (AtkValue *obj,
+ const GValue *value)
+{
+ GtkWidget *widget;
+
+ g_return_val_if_fail (GAIL_IS_RANGE (obj), FALSE);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return FALSE;
+
+ if (G_VALUE_HOLDS_DOUBLE (value))
+ {
+ GtkRange *range = GTK_RANGE (widget);
+ gdouble new_value;
+
+ new_value = g_value_get_double (value);
+ gtk_range_set_value (range, new_value);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static void
+gail_range_finalize (GObject *object)
+{
+ GailRange *range = GAIL_RANGE (object);
+
+ if (range->adjustment)
+ {
+ /*
+ * The GtkAdjustment may live on so we need to dicsonnect the
+ * signal handler
+ */
+ if (GAIL_ADJUSTMENT (range->adjustment)->adjustment)
+ {
+ g_signal_handlers_disconnect_by_func (GAIL_ADJUSTMENT (range->adjustment)->adjustment,
+ (void *)gail_range_value_changed,
+ range);
+ }
+ g_object_unref (range->adjustment);
+ range->adjustment = NULL;
+ }
+ range->activate_keybinding=NULL;
+ range->activate_description=NULL;
+ if (range->action_idle_handler)
+ {
+ g_source_remove (range->action_idle_handler);
+ range->action_idle_handler = 0;
+ }
+
+ G_OBJECT_CLASS (gail_range_parent_class)->finalize (object);
+}
+
+
+static void
+gail_range_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkAdjustment *adj;
+ GtkWidget *widget = GTK_WIDGET (obj);
+ GailRange *range = GAIL_RANGE (gtk_widget_get_accessible (widget));
+
+ if (strcmp (pspec->name, "adjustment") == 0)
+ {
+ /*
+ * Get rid of the GailAdjustment for the GtkAdjustment
+ * which was associated with the range.
+ */
+ if (range->adjustment)
+ {
+ g_object_unref (range->adjustment);
+ range->adjustment = NULL;
+ }
+ /*
+ * Create the GailAdjustment when notify for "adjustment" property
+ * is received
+ */
+ adj = gtk_range_get_adjustment (GTK_RANGE (widget));
+ range->adjustment = gail_adjustment_new (adj);
+ g_signal_connect (adj,
+ "value-changed",
+ G_CALLBACK (gail_range_value_changed),
+ range);
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_range_parent_class)->notify_gtk (obj, pspec);
+}
+
+static void
+gail_range_value_changed (GtkAdjustment *adjustment,
+ gpointer data)
+{
+ GailRange *range;
+
+ g_return_if_fail (adjustment != NULL);
+ gail_return_if_fail (data != NULL);
+
+ range = GAIL_RANGE (data);
+
+ g_object_notify (G_OBJECT (range), "accessible-value");
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ iface->do_action = gail_range_do_action;
+ iface->get_n_actions = gail_range_get_n_actions;
+ iface->get_description = gail_range_get_description;
+ iface->get_keybinding = gail_range_get_keybinding;
+ iface->get_name = gail_range_action_get_name;
+ iface->set_description = gail_range_set_description;
+}
+
+static gboolean
+gail_range_do_action (AtkAction *action,
+ gint i)
+{
+ GailRange *range;
+ GtkWidget *widget;
+ gboolean return_value = TRUE;
+
+ range = GAIL_RANGE (action);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return FALSE;
+ if (!gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+ if(i==0)
+ {
+ if (range->action_idle_handler)
+ return_value = FALSE;
+ else
+ range->action_idle_handler = gdk_threads_add_idle (idle_do_action, range);
+ }
+ else
+ return_value = FALSE;
+ return return_value;
+}
+
+static gboolean
+idle_do_action (gpointer data)
+{
+ GailRange *range;
+ GtkWidget *widget;
+
+ range = GAIL_RANGE (data);
+ range->action_idle_handler = 0;
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (range));
+ if (widget == NULL /* State is defunct */ ||
+ !gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ gtk_widget_activate (widget);
+
+ return FALSE;
+}
+
+static gint
+gail_range_get_n_actions (AtkAction *action)
+{
+ return 1;
+}
+
+static const gchar*
+gail_range_get_description (AtkAction *action,
+ gint i)
+{
+ GailRange *range;
+ const gchar *return_value;
+
+ range = GAIL_RANGE (action);
+ if (i==0)
+ return_value = range->activate_description;
+ else
+ return_value = NULL;
+ return return_value;
+}
+
+static const gchar*
+gail_range_get_keybinding (AtkAction *action,
+ gint i)
+{
+ GailRange *range;
+ gchar *return_value = NULL;
+ range = GAIL_RANGE (action);
+ if(i==0)
+ {
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkRelationSet *set;
+ AtkRelation *relation;
+ GPtrArray *target;
+ gpointer target_object;
+ guint key_val;
+
+ range = GAIL_RANGE (action);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (range));
+ if (widget == NULL)
+ return NULL;
+ set = atk_object_ref_relation_set (ATK_OBJECT (action));
+
+ if (!set)
+ return NULL;
+ label = NULL;
+ relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
+ if (relation)
+ {
+ target = atk_relation_get_target (relation);
+ target_object = g_ptr_array_index (target, 0);
+ label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
+ }
+ g_object_unref (set);
+ if (GTK_IS_LABEL (label))
+ {
+ key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
+ if (key_val != GDK_KEY_VoidSymbol)
+ return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
+ }
+ g_free (range->activate_keybinding);
+ range->activate_keybinding = return_value;
+ }
+ return return_value;
+}
+
+static const gchar*
+gail_range_action_get_name (AtkAction *action,
+ gint i)
+{
+ const gchar *return_value;
+
+ if (i==0)
+ return_value = "activate";
+ else
+ return_value = NULL;
+
+ return return_value;
+}
+
+static gboolean
+gail_range_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc)
+{
+ GailRange *range;
+ gchar **value;
+
+ range = GAIL_RANGE (action);
+
+ if (i==0)
+ value = &range->activate_description;
+ else
+ value = NULL;
+
+ if (value)
+ {
+ g_free (*value);
+ *value = g_strdup (desc);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_RANGE_H__
+#define __GAIL_RANGE_H__
+
+#include "gailwidget.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_RANGE (gail_range_get_type ())
+#define GAIL_RANGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RANGE, GailRange))
+#define GAIL_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RANGE, GailRangeClass))
+#define GAIL_IS_RANGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RANGE))
+#define GAIL_IS_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RANGE))
+#define GAIL_RANGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RANGE, GailRangeClass))
+
+typedef struct _GailRange GailRange;
+typedef struct _GailRangeClass GailRangeClass;
+
+struct _GailRange
+{
+ GailWidget parent;
+
+ AtkObject *adjustment;
+ gchar *activate_description;
+ gchar *activate_keybinding;
+ guint action_idle_handler;
+
+};
+
+GType gail_range_get_type (void);
+
+struct _GailRangeClass
+{
+ GailWidgetClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_RANGE_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailrenderercell.h"
+
+static void gail_renderer_cell_class_init (GailRendererCellClass *klass);
+static void gail_renderer_cell_init (GailRendererCell *renderer_cell);
+
+static void gail_renderer_cell_finalize (GObject *object);
+
+G_DEFINE_TYPE (GailRendererCell, gail_renderer_cell, GAIL_TYPE_CELL)
+
+static void
+gail_renderer_cell_class_init (GailRendererCellClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ klass->property_list = NULL;
+
+ gobject_class->finalize = gail_renderer_cell_finalize;
+}
+
+static void
+gail_renderer_cell_init (GailRendererCell *renderer_cell)
+{
+ renderer_cell->renderer = NULL;
+}
+
+static void
+gail_renderer_cell_finalize (GObject *object)
+{
+ GailRendererCell *renderer_cell = GAIL_RENDERER_CELL (object);
+
+ if (renderer_cell->renderer)
+ g_object_unref (renderer_cell->renderer);
+ G_OBJECT_CLASS (gail_renderer_cell_parent_class)->finalize (object);
+}
+
+gboolean
+gail_renderer_cell_update_cache (GailRendererCell *cell,
+ gboolean emit_change_signal)
+{
+ GailRendererCellClass *class = GAIL_RENDERER_CELL_GET_CLASS(cell);
+ if (class->update_cache)
+ return (class->update_cache)(cell, emit_change_signal);
+ return FALSE;
+}
+
+AtkObject*
+gail_renderer_cell_new (void)
+{
+ GObject *object;
+ AtkObject *atk_object;
+
+ object = g_object_new (GAIL_TYPE_RENDERER_CELL, NULL);
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ atk_object = ATK_OBJECT (object);
+ atk_object->role = ATK_ROLE_TABLE_CELL;
+
+ return atk_object;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_RENDERER_CELL_H__
+#define __GAIL_RENDERER_CELL_H__
+
+#include <atk/atk.h>
+#include "gailcell.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_RENDERER_CELL (gail_renderer_cell_get_type ())
+#define GAIL_RENDERER_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RENDERER_CELL, GailRendererCell))
+#define GAIL_RENDERER_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RENDERER_CELL, GailRendererCellClass))
+#define GAIL_IS_RENDERER_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RENDERER_CELL))
+#define GAIL_IS_RENDERER_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RENDERER_CELL))
+#define GAIL_RENDERER_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RENDERER_CELL, GailRendererCellClass))
+
+typedef struct _GailRendererCell GailRendererCell;
+typedef struct _GailRendererCellClass GailRendererCellClass;
+
+struct _GailRendererCell
+{
+ GailCell parent;
+ GtkCellRenderer *renderer;
+};
+
+GType gail_renderer_cell_get_type (void);
+
+struct _GailRendererCellClass
+{
+ GailCellClass parent_class;
+ gchar **property_list;
+ gboolean (*update_cache)(GailRendererCell *cell, gboolean emit_change_signal);
+};
+
+gboolean
+gail_renderer_cell_update_cache (GailRendererCell *cell, gboolean emit_change_signal);
+
+AtkObject *gail_renderer_cell_new (void);
+
+G_END_DECLS
+
+#endif /* __GAIL_TREE_VIEW_TEXT_CELL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2004 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailscale.h"
+#include <libgail-util/gailmisc.h>
+
+static void gail_scale_class_init (GailScaleClass *klass);
+
+static void gail_scale_init (GailScale *scale);
+
+static void gail_scale_real_initialize (AtkObject *obj,
+ gpointer data);
+static void gail_scale_notify (GObject *obj,
+ GParamSpec *pspec);
+static void gail_scale_finalize (GObject *object);
+
+/* atktext.h */
+static void atk_text_interface_init (AtkTextIface *iface);
+
+static gchar* gail_scale_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gunichar gail_scale_get_character_at_offset
+ (AtkText *text,
+ gint offset);
+static gchar* gail_scale_get_text_before_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_scale_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_scale_get_text_after_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gint gail_scale_get_character_count (AtkText *text);
+static void gail_scale_get_character_extents
+ (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static gint gail_scale_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static AtkAttributeSet* gail_scale_get_run_attributes
+ (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet* gail_scale_get_default_attributes
+ (AtkText *text);
+
+G_DEFINE_TYPE_WITH_CODE (GailScale, gail_scale, GAIL_TYPE_RANGE,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
+
+static void
+gail_scale_class_init (GailScaleClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->initialize = gail_scale_real_initialize;
+
+ gobject_class->finalize = gail_scale_finalize;
+ gobject_class->notify = gail_scale_notify;
+}
+
+static void
+gail_scale_init (GailScale *scale)
+{
+}
+
+static void
+gail_scale_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GailScale *gail_scale;
+ const gchar *txt;
+ PangoLayout *layout;
+
+ ATK_OBJECT_CLASS (gail_scale_parent_class)->initialize (obj, data);
+
+ gail_scale = GAIL_SCALE (obj);
+ gail_scale->textutil = gail_text_util_new ();
+
+ layout = gtk_scale_get_layout (GTK_SCALE (data));
+ if (layout)
+ {
+ txt = pango_layout_get_text (layout);
+ if (txt)
+ {
+ gail_text_util_text_setup (gail_scale->textutil, txt);
+ }
+ }
+}
+
+static void
+gail_scale_finalize (GObject *object)
+{
+ GailScale *scale = GAIL_SCALE (object);
+
+ g_object_unref (scale->textutil);
+ G_OBJECT_CLASS (gail_scale_parent_class)->finalize (object);
+
+}
+
+static void
+gail_scale_notify (GObject *obj,
+ GParamSpec *pspec)
+{
+ GailScale *scale = GAIL_SCALE (obj);
+
+ if (strcmp (pspec->name, "accessible-value") == 0)
+ {
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget)
+ {
+ GtkScale *gtk_scale;
+ PangoLayout *layout;
+ const gchar *txt;
+
+ gtk_scale = GTK_SCALE (widget);
+ layout = gtk_scale_get_layout (gtk_scale);
+ if (layout)
+ {
+ txt = pango_layout_get_text (layout);
+ if (txt)
+ {
+ g_signal_emit_by_name (obj, "text_changed::delete", 0,
+ gtk_text_buffer_get_char_count (scale->textutil->buffer));
+ gail_text_util_text_setup (scale->textutil, txt);
+ g_signal_emit_by_name (obj, "text_changed::insert", 0,
+ g_utf8_strlen (txt, -1));
+ }
+ }
+ }
+ }
+ G_OBJECT_CLASS (gail_scale_parent_class)->notify (obj, pspec);
+}
+
+/* atktext.h */
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_scale_get_text;
+ iface->get_character_at_offset = gail_scale_get_character_at_offset;
+ iface->get_text_before_offset = gail_scale_get_text_before_offset;
+ iface->get_text_at_offset = gail_scale_get_text_at_offset;
+ iface->get_text_after_offset = gail_scale_get_text_after_offset;
+ iface->get_character_count = gail_scale_get_character_count;
+ iface->get_character_extents = gail_scale_get_character_extents;
+ iface->get_offset_at_point = gail_scale_get_offset_at_point;
+ iface->get_run_attributes = gail_scale_get_run_attributes;
+ iface->get_default_attributes = gail_scale_get_default_attributes;
+}
+
+static gchar*
+gail_scale_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *widget;
+ GailScale *scale;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ scale = GAIL_SCALE (text);
+ return gail_text_util_get_substring (scale->textutil,
+ start_pos, end_pos);
+}
+
+static gchar*
+gail_scale_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GailScale *scale;
+ PangoLayout *layout;
+ gchar *txt;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ scale = GAIL_SCALE (text);
+ layout = gtk_scale_get_layout (GTK_SCALE (widget));
+ if (layout)
+ {
+ txt = gail_text_util_get_text (scale->textutil,
+ layout, GAIL_BEFORE_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+ }
+ else
+ txt = NULL;
+
+ return txt;
+}
+
+static gchar*
+gail_scale_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GailScale *scale;
+ PangoLayout *layout;
+ gchar *txt;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ scale = GAIL_SCALE (text);
+ layout = gtk_scale_get_layout (GTK_SCALE (widget));
+ if (layout)
+ {
+ txt = gail_text_util_get_text (scale->textutil,
+ layout, GAIL_AT_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+ }
+ else
+ txt = NULL;
+
+ return txt;
+}
+
+static gchar*
+gail_scale_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GailScale *scale;
+ PangoLayout *layout;
+ gchar *txt;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ scale = GAIL_SCALE (text);
+ layout = gtk_scale_get_layout (GTK_SCALE (widget));
+ if (layout)
+ {
+ txt = gail_text_util_get_text (scale->textutil,
+ layout, GAIL_AFTER_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+ }
+ else
+ txt = NULL;
+
+ return txt;
+}
+
+static gint
+gail_scale_get_character_count (AtkText *text)
+{
+ GtkWidget *widget;
+ GailScale *scale;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ scale = GAIL_SCALE (text);
+ if (scale->textutil->buffer)
+ return gtk_text_buffer_get_char_count (scale->textutil->buffer);
+ else
+ return 0;
+
+}
+
+static void
+gail_scale_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkScale *scale;
+ PangoRectangle char_rect;
+ PangoLayout *layout;
+ gint index, x_layout, y_layout;
+ const gchar *scale_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ scale = GTK_SCALE (widget);
+ layout = gtk_scale_get_layout (scale);
+ if (!layout)
+ return;
+ scale_text = pango_layout_get_text (layout);
+ if (!scale_text)
+ return;
+ index = g_utf8_offset_to_pointer (scale_text, offset) - scale_text;
+ gtk_scale_get_layout_offsets (scale, &x_layout, &y_layout);
+ pango_layout_index_to_pos (layout, index, &char_rect);
+ gail_misc_get_extents_from_pango_rectangle (widget, &char_rect,
+ x_layout, y_layout, x, y, width, height, coords);
+}
+
+static gint
+gail_scale_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkScale *scale;
+ PangoLayout *layout;
+ gint index, x_layout, y_layout;
+ const gchar *scale_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ scale = GTK_SCALE (widget);
+ layout = gtk_scale_get_layout (scale);
+ if (!layout)
+ return -1;
+ scale_text = pango_layout_get_text (layout);
+ if (!scale_text)
+ return -1;
+
+ gtk_scale_get_layout_offsets (scale, &x_layout, &y_layout);
+ index = gail_misc_get_index_at_point_in_layout (widget,
+ layout,
+ x_layout, y_layout, x, y, coords);
+ if (index == -1)
+ {
+ if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
+ index = g_utf8_strlen (scale_text, -1);
+ }
+ else
+ index = g_utf8_pointer_to_offset (scale_text, scale_text + index);
+
+ return index;
+}
+
+static AtkAttributeSet*
+gail_scale_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkScale *scale;
+ AtkAttributeSet *at_set = NULL;
+ GtkTextDirection dir;
+ PangoLayout *layout;
+ const gchar *scale_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ scale = GTK_SCALE (widget);
+
+ layout = gtk_scale_get_layout (scale);
+ if (!layout)
+ return at_set;
+ scale_text = pango_layout_get_text (layout);
+ if (!scale_text)
+ return at_set;
+
+ dir = gtk_widget_get_direction (widget);
+ if (dir == GTK_TEXT_DIR_RTL)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_DIRECTION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
+ }
+
+ at_set = gail_misc_layout_get_run_attributes (at_set,
+ layout,
+ (gchar *)scale_text,
+ offset,
+ start_offset,
+ end_offset);
+ return at_set;
+}
+
+static AtkAttributeSet*
+gail_scale_get_default_attributes (AtkText *text)
+{
+ GtkWidget *widget;
+ AtkAttributeSet *at_set = NULL;
+ PangoLayout *layout;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ layout = gtk_scale_get_layout (GTK_SCALE (widget));
+ if (layout)
+ {
+ at_set = gail_misc_get_default_attributes (at_set,
+ layout,
+ widget);
+ }
+ return at_set;
+}
+
+static gunichar
+gail_scale_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GtkWidget *widget;
+ GtkScale *scale;
+ PangoLayout *layout;
+ const gchar *string;
+ gchar *index;
+ gunichar c;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return '\0';
+
+ scale = GTK_SCALE (widget);
+
+ layout = gtk_scale_get_layout (scale);
+ if (!layout)
+ return '\0';
+ string = pango_layout_get_text (layout);
+ if (offset >= g_utf8_strlen (string, -1))
+ c = '\0';
+ else
+ {
+ index = g_utf8_offset_to_pointer (string, offset);
+
+ c = g_utf8_get_char (index);
+ }
+
+ return c;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2004 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_SCALE_H__
+#define __GAIL_SCALE_H__
+
+#include "gailrange.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_SCALE (gail_scale_get_type ())
+#define GAIL_SCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SCALE, GailScale))
+#define GAIL_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SCALE, GailScaleClass))
+#define GAIL_IS_SCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SCALE))
+#define GAIL_IS_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SCALE))
+#define GAIL_SCALE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SCALE, GailScaleClass))
+
+typedef struct _GailScale GailScale;
+typedef struct _GailScaleClass GailScaleClass;
+
+struct _GailScale
+{
+ GailRange parent;
+
+ GailTextUtil *textutil;
+};
+
+GType gail_scale_get_type (void);
+
+struct _GailScaleClass
+{
+ GailRangeClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_SCALE_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2008 Jan Arne Petersen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include "gailscalebutton.h"
+#include "gailadjustment.h"
+#include "gail-private-macros.h"
+
+#include <string.h>
+
+static void gail_scale_button_class_init (GailScaleButtonClass *klass);
+static void gail_scale_button_init (GailScaleButton *button);
+
+/* GailWidget */
+static void gail_scale_button_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+
+/* AtkObject */
+static void gail_scale_button_real_initialize (AtkObject *obj,
+ gpointer data);
+
+/* AtkAction */
+static void atk_action_interface_init (AtkActionIface *iface);
+static gboolean gail_scale_button_do_action (AtkAction *action,
+ gint i);
+static gint gail_scale_button_get_n_actions (AtkAction *action);
+static const gchar* gail_scale_button_get_description(AtkAction *action,
+ gint i);
+static const gchar* gail_scale_button_action_get_name(AtkAction *action,
+ gint i);
+static const gchar* gail_scale_button_get_keybinding (AtkAction *action,
+ gint i);
+static gboolean gail_scale_button_set_description(AtkAction *action,
+ gint i,
+ const gchar *desc);
+
+/* AtkValue */
+static void atk_value_interface_init (AtkValueIface *iface);
+static void gail_scale_button_get_current_value (AtkValue *obj,
+ GValue *value);
+static void gail_scale_button_get_maximum_value (AtkValue *obj,
+ GValue *value);
+static void gail_scale_button_get_minimum_value (AtkValue *obj,
+ GValue *value);
+static void gail_scale_button_get_minimum_increment (AtkValue *obj,
+ GValue *value);
+static gboolean gail_scale_button_set_current_value (AtkValue *obj,
+ const GValue *value);
+static void gail_scale_button_value_changed (GtkAdjustment *adjustment,
+ gpointer data);
+
+G_DEFINE_TYPE_WITH_CODE (GailScaleButton, gail_scale_button, GAIL_TYPE_BUTTON,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init));
+
+static void
+gail_scale_button_class_init (GailScaleButtonClass *klass)
+{
+ AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
+ GailWidgetClass *widget_class = GAIL_WIDGET_CLASS (klass);
+
+ atk_object_class->initialize = gail_scale_button_real_initialize;
+
+ widget_class->notify_gtk = gail_scale_button_real_notify_gtk;
+}
+
+static void
+gail_scale_button_init (GailScaleButton *button)
+{
+}
+
+static void
+gail_scale_button_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GailScaleButton *scale_button = GAIL_SCALE_BUTTON (obj);
+ GtkScaleButton *gtk_scale_button;
+ GtkAdjustment *gtk_adjustment;
+
+ ATK_OBJECT_CLASS (gail_scale_button_parent_class)->initialize (obj, data);
+
+ gtk_scale_button = GTK_SCALE_BUTTON (data);
+ gtk_adjustment = gtk_scale_button_get_adjustment (gtk_scale_button);
+ /*
+ * If a GtkAdjustment already exists for the scale_button,
+ * create the GailAdjustment
+ */
+ if (gtk_adjustment)
+ {
+ scale_button->adjustment = gail_adjustment_new (gtk_adjustment);
+ g_signal_connect (gtk_adjustment,
+ "value-changed",
+ G_CALLBACK (gail_scale_button_value_changed),
+ obj);
+ }
+ else
+ scale_button->adjustment = NULL;
+
+ obj->role = ATK_ROLE_SLIDER;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ iface->do_action = gail_scale_button_do_action;
+ iface->get_n_actions = gail_scale_button_get_n_actions;
+ iface->get_description = gail_scale_button_get_description;
+ iface->get_keybinding = gail_scale_button_get_keybinding;
+ iface->get_name = gail_scale_button_action_get_name;
+ iface->set_description = gail_scale_button_set_description;
+}
+
+static gboolean
+gail_scale_button_do_action(AtkAction *action,
+ gint i)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
+ if (widget == NULL)
+ return FALSE;
+
+ if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
+ return FALSE;
+
+ switch (i) {
+ case 0:
+ g_signal_emit_by_name (widget, "popup");
+ return TRUE;
+ case 1:
+ g_signal_emit_by_name (widget, "podown");
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static gint
+gail_scale_button_get_n_actions (AtkAction *action)
+{
+ return 2;
+}
+
+static const gchar*
+gail_scale_button_get_description (AtkAction *action,
+ gint i)
+{
+ return NULL;
+}
+
+static const gchar*
+gail_scale_button_action_get_name (AtkAction *action,
+ gint i)
+{
+ switch (i) {
+ case 0:
+ return "popup";
+ case 1:
+ return "popdown";
+ default:
+ return NULL;
+ }
+}
+
+static const gchar*
+gail_scale_button_get_keybinding (AtkAction *action,
+ gint i)
+{
+ return NULL;
+}
+
+static gboolean
+gail_scale_button_set_description (AtkAction *action,
+ gint i,
+ const gchar *desc)
+{
+ return FALSE;
+}
+
+
+static void
+atk_value_interface_init (AtkValueIface *iface)
+{
+ iface->get_current_value = gail_scale_button_get_current_value;
+ iface->get_maximum_value = gail_scale_button_get_maximum_value;
+ iface->get_minimum_value = gail_scale_button_get_minimum_value;
+ iface->get_minimum_increment = gail_scale_button_get_minimum_increment;
+ iface->set_current_value = gail_scale_button_set_current_value;
+}
+
+static void
+gail_scale_button_get_current_value (AtkValue *obj,
+ GValue *value)
+{
+ GailScaleButton *scale_button;
+
+ g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
+
+ scale_button = GAIL_SCALE_BUTTON (obj);
+ if (scale_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_current_value (ATK_VALUE (scale_button->adjustment), value);
+}
+
+static void
+gail_scale_button_get_maximum_value (AtkValue *obj,
+ GValue *value)
+{
+ GailScaleButton *scale_button;
+
+ g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
+
+ scale_button = GAIL_SCALE_BUTTON (obj);
+ if (scale_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_maximum_value (ATK_VALUE (scale_button->adjustment), value);
+}
+
+static void
+gail_scale_button_get_minimum_value (AtkValue *obj,
+ GValue *value)
+{
+ GailScaleButton *scale_button;
+
+ g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
+
+ scale_button = GAIL_SCALE_BUTTON (obj);
+ if (scale_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_minimum_value (ATK_VALUE (scale_button->adjustment), value);
+}
+
+static void
+gail_scale_button_get_minimum_increment (AtkValue *obj,
+ GValue *value)
+{
+ GailScaleButton *scale_button;
+
+ g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
+
+ scale_button = GAIL_SCALE_BUTTON (obj);
+ if (scale_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_minimum_increment (ATK_VALUE (scale_button->adjustment), value);
+}
+
+static gboolean
+gail_scale_button_set_current_value (AtkValue *obj,
+ const GValue *value)
+{
+ GailScaleButton *scale_button;
+
+ g_return_val_if_fail (GAIL_IS_SCALE_BUTTON (obj), FALSE);
+
+ scale_button = GAIL_SCALE_BUTTON (obj);
+ if (scale_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return FALSE;
+
+ return atk_value_set_current_value (ATK_VALUE (scale_button->adjustment), value);
+}
+
+static void
+gail_scale_button_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkScaleButton *gtk_scale_button;
+ GailScaleButton *scale_button;
+
+ g_return_if_fail (GTK_IS_SCALE_BUTTON (obj));
+
+ gtk_scale_button = GTK_SCALE_BUTTON (obj);
+ scale_button = GAIL_SCALE_BUTTON (gtk_widget_get_accessible (GTK_WIDGET (gtk_scale_button)));
+
+ if (strcmp (pspec->name, "adjustment") == 0)
+ {
+ /*
+ * Get rid of the GailAdjustment for the GtkAdjustment
+ * which was associated with the scale_button.
+ */
+ GtkAdjustment* gtk_adjustment;
+
+ if (scale_button->adjustment)
+ {
+ g_object_unref (scale_button->adjustment);
+ scale_button->adjustment = NULL;
+ }
+ /*
+ * Create the GailAdjustment when notify for "adjustment" property
+ * is received
+ */
+ gtk_adjustment = gtk_scale_button_get_adjustment (gtk_scale_button);
+ scale_button->adjustment = gail_adjustment_new (gtk_adjustment);
+ g_signal_connect (gtk_adjustment,
+ "value-changed",
+ G_CALLBACK (gail_scale_button_value_changed),
+ scale_button);
+ }
+ else
+ {
+ GAIL_WIDGET_CLASS (gail_scale_button_parent_class)->notify_gtk (obj, pspec);
+ }
+}
+
+static void
+gail_scale_button_value_changed (GtkAdjustment *adjustment,
+ gpointer data)
+{
+ GailScaleButton *scale_button;
+
+ gail_return_if_fail (adjustment != NULL);
+ gail_return_if_fail (data != NULL);
+
+ scale_button = GAIL_SCALE_BUTTON (data);
+
+ g_object_notify (G_OBJECT (scale_button), "accessible-value");
+}
+
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2008 Jan Arne Petersen <jap@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_SCALE_BUTTON_H__
+#define __GAIL_SCALE_BUTTON_H__
+
+#include <gtk/gtk.h>
+#include "gailbutton.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_SCALE_BUTTON (gail_scale_button_get_type ())
+#define GAIL_SCALE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SCALE_BUTTON, GailScaleButton))
+#define GAIL_SCALE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SCALE_BUTTON, GailScaleButtonClass))
+#define GAIL_IS_SCALE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SCALE_BUTTON))
+#define GAIL_IS_SCALE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SCALE_BUTTON))
+#define GAIL_SCALE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SCALE_BUTTON, GailScaleButtonClass))
+
+typedef struct _GailScaleButton GailScaleButton;
+typedef struct _GailScaleButtonClass GailScaleButtonClass;
+
+struct _GailScaleButton
+{
+ GailButton parent;
+
+ AtkObject *adjustment;
+};
+
+struct _GailScaleButtonClass
+{
+ GailButtonClass parent_class;
+};
+
+GType gail_scale_button_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GAIL_SCALE_BUTTON_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailscrollbar.h"
+
+static void gail_scrollbar_class_init (GailScrollbarClass *klass);
+static void gail_scrollbar_init (GailScrollbar *accessible);
+static void gail_scrollbar_initialize (AtkObject *accessible,
+ gpointer data);
+
+static gint gail_scrollbar_get_index_in_parent (AtkObject *accessible);
+
+G_DEFINE_TYPE (GailScrollbar, gail_scrollbar, GAIL_TYPE_RANGE)
+
+static void
+gail_scrollbar_class_init (GailScrollbarClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->initialize = gail_scrollbar_initialize;
+ class->get_index_in_parent = gail_scrollbar_get_index_in_parent;
+}
+
+static void
+gail_scrollbar_init (GailScrollbar *accessible)
+{
+}
+
+static void
+gail_scrollbar_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_scrollbar_parent_class)->initialize (accessible, data);
+
+ accessible->role = ATK_ROLE_SCROLL_BAR;
+}
+
+static gint
+gail_scrollbar_get_index_in_parent (AtkObject *accessible)
+{
+ GtkWidget *widget;
+ GtkWidget *parent;
+ GtkWidget *child;
+ GtkScrolledWindow *scrolled_window;
+ gint id;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ {
+ /*
+ * State is defunct
+ */
+ return -1;
+ }
+ g_return_val_if_fail (GTK_IS_SCROLLBAR (widget), -1);
+
+ parent = gtk_widget_get_parent (widget);
+ if (!GTK_IS_SCROLLED_WINDOW (parent))
+ return ATK_OBJECT_CLASS (gail_scrollbar_parent_class)->get_index_in_parent (accessible);
+
+ scrolled_window = GTK_SCROLLED_WINDOW (parent);
+ id = 0;
+ child = gtk_bin_get_child (GTK_BIN (scrolled_window));
+ if (child)
+ {
+ if (widget == child)
+ return id;
+ id++;
+ }
+
+ child = gtk_scrolled_window_get_hscrollbar (scrolled_window);
+ if (child)
+ {
+ if (widget == child)
+ return id;
+ id++;
+ }
+ child = gtk_scrolled_window_get_vscrollbar (scrolled_window);
+ if (child)
+ {
+ if (widget == child)
+ return id;
+ }
+
+ return -1;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_SCROLLBAR_H__
+#define __GAIL_SCROLLBAR_H__
+
+#include "gailrange.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_SCROLLBAR (gail_scrollbar_get_type ())
+#define GAIL_SCROLLBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SCROLLBAR, GailScrollbar))
+#define GAIL_SCROLLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SCROLLBAR, GailScrollbarClass))
+#define GAIL_IS_SCROLLBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SCROLLBAR))
+#define GAIL_IS_SCROLLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SCROLLBAR))
+#define GAIL_SCROLLBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SCROLLBAR, GailScrollbarClass))
+
+typedef struct _GailScrollbar GailScrollbar;
+typedef struct _GailScrollbarClass GailScrollbarClass;
+
+struct _GailScrollbar
+{
+ GailRange parent;
+};
+
+GType gail_scrollbar_get_type (void);
+
+struct _GailScrollbarClass
+{
+ GailRangeClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_SCROLLBAR_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailscrolledwindow.h"
+
+
+static void gail_scrolled_window_class_init (GailScrolledWindowClass *klass);
+static void gail_scrolled_window_init (GailScrolledWindow *window);
+static void gail_scrolled_window_real_initialize
+ (AtkObject *obj,
+ gpointer data);
+
+static gint gail_scrolled_window_get_n_children (AtkObject *object);
+static AtkObject* gail_scrolled_window_ref_child (AtkObject *obj,
+ gint child);
+static void gail_scrolled_window_scrollbar_visibility_changed
+ (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data);
+
+G_DEFINE_TYPE (GailScrolledWindow, gail_scrolled_window, GAIL_TYPE_CONTAINER)
+
+static void
+gail_scrolled_window_class_init (GailScrolledWindowClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->get_n_children = gail_scrolled_window_get_n_children;
+ class->ref_child = gail_scrolled_window_ref_child;
+ class->initialize = gail_scrolled_window_real_initialize;
+}
+
+static void
+gail_scrolled_window_init (GailScrolledWindow *window)
+{
+}
+
+static void
+gail_scrolled_window_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkScrolledWindow *window;
+
+ ATK_OBJECT_CLASS (gail_scrolled_window_parent_class)->initialize (obj, data);
+
+ window = GTK_SCROLLED_WINDOW (data);
+
+ g_signal_connect_data (gtk_scrolled_window_get_hscrollbar (window), "notify::visible",
+ G_CALLBACK (gail_scrolled_window_scrollbar_visibility_changed),
+ obj, NULL, FALSE);
+ g_signal_connect_data (gtk_scrolled_window_get_vscrollbar (window), "notify::visible",
+ G_CALLBACK (gail_scrolled_window_scrollbar_visibility_changed),
+ obj, NULL, FALSE);
+
+ obj->role = ATK_ROLE_SCROLL_PANE;
+}
+
+static gint
+gail_scrolled_window_get_n_children (AtkObject *object)
+{
+ GtkWidget *widget;
+ GtkScrolledWindow *gtk_window;
+ GList *children;
+ gint n_children;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (object));
+ if (widget == NULL)
+ /* Object is defunct */
+ return 0;
+
+ gtk_window = GTK_SCROLLED_WINDOW (widget);
+
+ /* Get the number of children returned by the backing GtkScrolledWindow */
+
+ children = gtk_container_get_children (GTK_CONTAINER(gtk_window));
+ n_children = g_list_length (children);
+ g_list_free (children);
+
+ /* Add one to the count for each visible scrollbar */
+
+ if (gtk_scrolled_window_get_hscrollbar (gtk_window))
+ n_children++;
+ if (gtk_scrolled_window_get_vscrollbar (gtk_window))
+ n_children++;
+ return n_children;
+}
+
+static AtkObject *
+gail_scrolled_window_ref_child (AtkObject *obj,
+ gint child)
+{
+ GtkWidget *widget;
+ GtkScrolledWindow *gtk_window;
+ GtkWidget *hscrollbar, *vscrollbar;
+ GList *children, *tmp_list;
+ gint n_children;
+ AtkObject *accessible = NULL;
+
+ g_return_val_if_fail (child >= 0, NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /* Object is defunct */
+ return NULL;
+
+ gtk_window = GTK_SCROLLED_WINDOW (widget);
+ hscrollbar = gtk_scrolled_window_get_hscrollbar (gtk_window);
+ vscrollbar = gtk_scrolled_window_get_vscrollbar (gtk_window);
+
+ children = gtk_container_get_children (GTK_CONTAINER (gtk_window));
+ n_children = g_list_length (children);
+
+ if (child == n_children)
+ {
+ if (gtk_scrolled_window_get_hscrollbar (gtk_window))
+ accessible = gtk_widget_get_accessible (hscrollbar);
+ else if (gtk_scrolled_window_get_vscrollbar (gtk_window))
+ accessible = gtk_widget_get_accessible (vscrollbar);
+ }
+ else if (child == n_children+1 &&
+ gtk_scrolled_window_get_hscrollbar (gtk_window) &&
+ gtk_scrolled_window_get_vscrollbar (gtk_window))
+ accessible = gtk_widget_get_accessible (vscrollbar);
+ else if (child < n_children)
+ {
+ tmp_list = g_list_nth (children, child);
+ if (tmp_list)
+ accessible = gtk_widget_get_accessible (
+ GTK_WIDGET (tmp_list->data));
+ }
+
+ g_list_free (children);
+ if (accessible)
+ g_object_ref (accessible);
+ return accessible;
+}
+
+static void
+gail_scrolled_window_scrollbar_visibility_changed (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ if (!strcmp (pspec->name, "visible"))
+ {
+ gint index;
+ gint n_children;
+ gboolean child_added = FALSE;
+ GList *children;
+ AtkObject *child;
+ GtkScrolledWindow *gtk_window;
+ GtkWidget *hscrollbar, *vscrollbar;
+ GailScrolledWindow *gail_window = GAIL_SCROLLED_WINDOW (user_data);
+ gchar *signal_name;
+
+ gtk_window = GTK_SCROLLED_WINDOW (gtk_accessible_get_widget (GTK_ACCESSIBLE (user_data)));
+ if (gtk_window == NULL)
+ return;
+ children = gtk_container_get_children (GTK_CONTAINER (gtk_window));
+ index = n_children = g_list_length (children);
+ g_list_free (children);
+
+ hscrollbar = gtk_scrolled_window_get_hscrollbar (gtk_window);
+ vscrollbar = gtk_scrolled_window_get_vscrollbar (gtk_window);
+
+ if ((gpointer) object == (gpointer) (hscrollbar))
+ {
+ if (gtk_scrolled_window_get_hscrollbar (gtk_window))
+ child_added = TRUE;
+
+ child = gtk_widget_get_accessible (hscrollbar);
+ }
+ else if ((gpointer) object == (gpointer) (vscrollbar))
+ {
+ if (gtk_scrolled_window_get_vscrollbar (gtk_window))
+ child_added = TRUE;
+
+ child = gtk_widget_get_accessible (vscrollbar);
+ if (gtk_scrolled_window_get_hscrollbar (gtk_window))
+ index = n_children+1;
+ }
+ else
+ {
+ g_assert_not_reached ();
+ return;
+ }
+
+ if (child_added)
+ signal_name = "children_changed::add";
+ else
+ signal_name = "children_changed::delete";
+
+ g_signal_emit_by_name (gail_window, signal_name, index, child, NULL);
+ }
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_SCROLLED_WINDOW_H__
+#define __GAIL_SCROLLED_WINDOW_H__
+
+#include "gailcontainer.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_SCROLLED_WINDOW (gail_scrolled_window_get_type ())
+#define GAIL_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SCROLLED_WINDOW, GailScrolledWindow))
+#define GAIL_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SCROLLED_WINDOW, GailScrolledWindowClass))
+#define GAIL_IS_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SCROLLED_WINDOW))
+#define GAIL_IS_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SCROLLED_WINDOW))
+#define GAIL_SCROLLED_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SCROLLED_WINDOW, GailScrolledWindowClass))
+
+typedef struct _GailScrolledWindow GailScrolledWindow;
+typedef struct _GailScrolledWindowClass GailScrolledWindowClass;
+
+struct _GailScrolledWindow
+{
+ GailContainer parent;
+};
+
+GType gail_scrolled_window_get_type (void);
+
+struct _GailScrolledWindowClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_SCROLLED_WINDOW_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailseparator.h"
+
+static void gail_separator_class_init (GailSeparatorClass *klass);
+static void gail_separator_init (GailSeparator *accessible);
+static void gail_separator_initialize (AtkObject *accessible,
+ gpointer data);
+
+G_DEFINE_TYPE (GailSeparator, gail_separator, GAIL_TYPE_WIDGET)
+
+static void
+gail_separator_class_init (GailSeparatorClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->initialize = gail_separator_initialize;
+}
+
+static void
+gail_separator_init (GailSeparator *accessible)
+{
+}
+
+static void
+gail_separator_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_separator_parent_class)->initialize (accessible, data);
+
+ accessible->role = ATK_ROLE_SEPARATOR;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_SEPARATOR_H__
+#define __GAIL_SEPARATOR_H__
+
+#include "gailwidget.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_SEPARATOR (gail_separator_get_type ())
+#define GAIL_SEPARATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SEPARATOR, GailSeparator))
+#define GAIL_SEPARATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SEPARATOR, GailSeparatorClass))
+#define GAIL_IS_SEPARATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SEPARATOR))
+#define GAIL_IS_SEPARATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SEPARATOR))
+#define GAIL_SEPARATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SEPARATOR, GailSeparatorClass))
+
+typedef struct _GailSeparator GailSeparator;
+typedef struct _GailSeparatorClass GailSeparatorClass;
+
+struct _GailSeparator
+{
+ GailWidget parent;
+};
+
+GType gail_separator_get_type (void);
+
+struct _GailSeparatorClass
+{
+ GailWidgetClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_SEPARATOR_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailspinbutton.h"
+#include "gailadjustment.h"
+#include "gail-private-macros.h"
+
+static void gail_spin_button_class_init (GailSpinButtonClass *klass);
+static void gail_spin_button_init (GailSpinButton *button);
+static void gail_spin_button_real_initialize (AtkObject *obj,
+ gpointer data);
+static void gail_spin_button_finalize (GObject *object);
+
+static void atk_value_interface_init (AtkValueIface *iface);
+
+static void gail_spin_button_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+
+static void gail_spin_button_get_current_value (AtkValue *obj,
+ GValue *value);
+static void gail_spin_button_get_maximum_value (AtkValue *obj,
+ GValue *value);
+static void gail_spin_button_get_minimum_value (AtkValue *obj,
+ GValue *value);
+static void gail_spin_button_get_minimum_increment (AtkValue *obj,
+ GValue *value);
+static gboolean gail_spin_button_set_current_value (AtkValue *obj,
+ const GValue *value);
+static void gail_spin_button_value_changed (GtkAdjustment *adjustment,
+ gpointer data);
+
+G_DEFINE_TYPE_WITH_CODE (GailSpinButton, gail_spin_button, GAIL_TYPE_ENTRY,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
+
+static void
+gail_spin_button_class_init (GailSpinButtonClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailWidgetClass *widget_class;
+
+ widget_class = (GailWidgetClass*)klass;
+
+ widget_class->notify_gtk = gail_spin_button_real_notify_gtk;
+
+ class->initialize = gail_spin_button_real_initialize;
+
+ gobject_class->finalize = gail_spin_button_finalize;
+}
+
+static void
+gail_spin_button_init (GailSpinButton *button)
+{
+}
+
+static void
+gail_spin_button_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkAdjustment *adjustment;
+ GailSpinButton *spin_button = GAIL_SPIN_BUTTON (obj);
+ GtkSpinButton *gtk_spin_button;
+
+ ATK_OBJECT_CLASS (gail_spin_button_parent_class)->initialize (obj, data);
+
+ gtk_spin_button = GTK_SPIN_BUTTON (data);
+ /*
+ * If a GtkAdjustment already exists for the spin_button,
+ * create the GailAdjustment
+ */
+ adjustment = gtk_spin_button_get_adjustment (gtk_spin_button);
+ if (adjustment)
+ {
+ spin_button->adjustment = gail_adjustment_new (adjustment);
+ g_signal_connect (adjustment,
+ "value-changed",
+ G_CALLBACK (gail_spin_button_value_changed),
+ obj);
+ }
+ else
+ spin_button->adjustment = NULL;
+
+ obj->role = ATK_ROLE_SPIN_BUTTON;
+
+}
+
+static void
+atk_value_interface_init (AtkValueIface *iface)
+{
+ iface->get_current_value = gail_spin_button_get_current_value;
+ iface->get_maximum_value = gail_spin_button_get_maximum_value;
+ iface->get_minimum_value = gail_spin_button_get_minimum_value;
+ iface->get_minimum_increment = gail_spin_button_get_minimum_increment;
+ iface->set_current_value = gail_spin_button_set_current_value;
+}
+
+static void
+gail_spin_button_get_current_value (AtkValue *obj,
+ GValue *value)
+{
+ GailSpinButton *spin_button;
+
+ g_return_if_fail (GAIL_IS_SPIN_BUTTON (obj));
+
+ spin_button = GAIL_SPIN_BUTTON (obj);
+ if (spin_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_current_value (ATK_VALUE (spin_button->adjustment), value);
+}
+
+static void
+gail_spin_button_get_maximum_value (AtkValue *obj,
+ GValue *value)
+{
+ GailSpinButton *spin_button;
+
+ g_return_if_fail (GAIL_IS_SPIN_BUTTON (obj));
+
+ spin_button = GAIL_SPIN_BUTTON (obj);
+ if (spin_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_maximum_value (ATK_VALUE (spin_button->adjustment), value);
+}
+
+static void
+gail_spin_button_get_minimum_value (AtkValue *obj,
+ GValue *value)
+{
+ GailSpinButton *spin_button;
+
+ g_return_if_fail (GAIL_IS_SPIN_BUTTON (obj));
+
+ spin_button = GAIL_SPIN_BUTTON (obj);
+ if (spin_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_minimum_value (ATK_VALUE (spin_button->adjustment), value);
+}
+
+static void
+gail_spin_button_get_minimum_increment (AtkValue *obj, GValue *value)
+{
+ GailSpinButton *spin_button;
+
+ g_return_if_fail (GAIL_IS_SPIN_BUTTON (obj));
+
+ spin_button = GAIL_SPIN_BUTTON (obj);
+ if (spin_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return;
+
+ atk_value_get_minimum_increment (ATK_VALUE (spin_button->adjustment), value);
+}
+
+static gboolean
+gail_spin_button_set_current_value (AtkValue *obj,
+ const GValue *value)
+{
+ GailSpinButton *spin_button;
+
+ g_return_val_if_fail (GAIL_IS_SPIN_BUTTON (obj), FALSE);
+
+ spin_button = GAIL_SPIN_BUTTON (obj);
+ if (spin_button->adjustment == NULL)
+ /*
+ * Adjustment has not been specified
+ */
+ return FALSE;
+
+ return atk_value_set_current_value (ATK_VALUE (spin_button->adjustment), value);
+}
+
+static void
+gail_spin_button_finalize (GObject *object)
+{
+ GailSpinButton *spin_button = GAIL_SPIN_BUTTON (object);
+
+ if (spin_button->adjustment)
+ {
+ g_object_unref (spin_button->adjustment);
+ spin_button->adjustment = NULL;
+ }
+ G_OBJECT_CLASS (gail_spin_button_parent_class)->finalize (object);
+}
+
+
+static void
+gail_spin_button_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkWidget *widget = GTK_WIDGET (obj);
+ GailSpinButton *spin_button = GAIL_SPIN_BUTTON (gtk_widget_get_accessible (widget));
+
+ if (strcmp (pspec->name, "adjustment") == 0)
+ {
+ /*
+ * Get rid of the GailAdjustment for the GtkAdjustment
+ * which was associated with the spin_button.
+ */
+ GtkAdjustment* adjustment;
+ GtkSpinButton* gtk_spin_button;
+
+ if (spin_button->adjustment)
+ {
+ g_object_unref (spin_button->adjustment);
+ spin_button->adjustment = NULL;
+ }
+ /*
+ * Create the GailAdjustment when notify for "adjustment" property
+ * is received
+ */
+ gtk_spin_button = GTK_SPIN_BUTTON (widget);
+ adjustment = gtk_spin_button_get_adjustment (gtk_spin_button);
+ spin_button->adjustment = gail_adjustment_new (adjustment);
+ g_signal_connect (adjustment,
+ "value-changed",
+ G_CALLBACK (gail_spin_button_value_changed),
+ spin_button);
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_spin_button_parent_class)->notify_gtk (obj, pspec);
+}
+
+
+static void
+gail_spin_button_value_changed (GtkAdjustment *adjustment,
+ gpointer data)
+{
+ GailSpinButton *spin_button;
+
+ gail_return_if_fail (adjustment != NULL);
+ gail_return_if_fail (data != NULL);
+
+ spin_button = GAIL_SPIN_BUTTON (data);
+
+ g_object_notify (G_OBJECT (spin_button), "accessible-value");
+}
+
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_SPIN_BUTTON_H__
+#define __GAIL_SPIN_BUTTON_H__
+
+#include "gailentry.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_SPIN_BUTTON (gail_spin_button_get_type ())
+#define GAIL_SPIN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SPIN_BUTTON, GailSpinButton))
+#define GAIL_SPIN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SPIN_BUTTON, GailSpinButtonClass))
+#define GAIL_IS_SPIN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SPIN_BUTTON))
+#define GAIL_IS_SPIN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SPIN_BUTTON))
+#define GAIL_SPIN_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SPIN_BUTTON, GailSpinButtonClass))
+
+typedef struct _GailSpinButton GailSpinButton;
+typedef struct _GailSpinButtonClass GailSpinButtonClass;
+
+struct _GailSpinButton
+{
+ GailEntry parent;
+
+ AtkObject *adjustment;
+};
+
+GType gail_spin_button_get_type (void);
+
+struct _GailSpinButtonClass
+{
+ GailEntryClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_SPIN_BUTTON_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailstatusbar.h"
+#include <libgail-util/gailmisc.h>
+
+static void gail_statusbar_class_init (GailStatusbarClass *klass);
+static void gail_statusbar_init (GailStatusbar *bar);
+static const gchar* gail_statusbar_get_name (AtkObject *obj);
+static gint gail_statusbar_get_n_children (AtkObject *obj);
+static AtkObject* gail_statusbar_ref_child (AtkObject *obj,
+ gint i);
+static void gail_statusbar_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static gint gail_statusbar_notify (GObject *obj,
+ GParamSpec *pspec,
+ gpointer user_data);
+static void gail_statusbar_finalize (GObject *object);
+static void gail_statusbar_init_textutil (GailStatusbar *statusbar,
+ GtkWidget *label);
+
+/* atktext.h */
+static void atk_text_interface_init (AtkTextIface *iface);
+
+static gchar* gail_statusbar_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gunichar gail_statusbar_get_character_at_offset
+ (AtkText *text,
+ gint offset);
+static gchar* gail_statusbar_get_text_before_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_statusbar_get_text_at_offset(AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_statusbar_get_text_after_offset
+ (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gint gail_statusbar_get_character_count (AtkText *text);
+static void gail_statusbar_get_character_extents
+ (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static gint gail_statusbar_get_offset_at_point(AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static AtkAttributeSet* gail_statusbar_get_run_attributes
+ (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet* gail_statusbar_get_default_attributes
+ (AtkText *text);
+static GtkWidget* get_label_from_statusbar (GtkWidget *statusbar);
+
+G_DEFINE_TYPE_WITH_CODE (GailStatusbar, gail_statusbar, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
+
+static void
+gail_statusbar_class_init (GailStatusbarClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailContainerClass *container_class;
+
+ container_class = (GailContainerClass*)klass;
+
+ gobject_class->finalize = gail_statusbar_finalize;
+
+ class->get_name = gail_statusbar_get_name;
+ class->get_n_children = gail_statusbar_get_n_children;
+ class->ref_child = gail_statusbar_ref_child;
+ class->initialize = gail_statusbar_real_initialize;
+ /*
+ * As we report the statusbar as having no children we are not interested
+ * in add and remove signals
+ */
+ container_class->add_gtk = NULL;
+ container_class->remove_gtk = NULL;
+}
+
+static void
+gail_statusbar_init (GailStatusbar *bar)
+{
+}
+
+static const gchar*
+gail_statusbar_get_name (AtkObject *obj)
+{
+ const gchar* name;
+
+ g_return_val_if_fail (GAIL_IS_STATUSBAR (obj), NULL);
+
+ name = ATK_OBJECT_CLASS (gail_statusbar_parent_class)->get_name (obj);
+ if (name != NULL)
+ return name;
+ else
+ {
+ /*
+ * Get the text on the label
+ */
+ GtkWidget *widget;
+ GtkWidget *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ g_return_val_if_fail (GTK_IS_STATUSBAR (widget), NULL);
+ label = get_label_from_statusbar (widget);
+ if (GTK_IS_LABEL (label))
+ return gtk_label_get_label (GTK_LABEL (label));
+ else
+ return NULL;
+ }
+}
+
+static gint
+gail_statusbar_get_n_children (AtkObject *obj)
+{
+ GtkWidget *widget;
+ GList *children;
+ gint count = 0;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return 0;
+
+ children = gtk_container_get_children (GTK_CONTAINER (widget));
+ if (children != NULL)
+ {
+ count = g_list_length (children);
+ g_list_free (children);
+ }
+
+ return count;
+}
+
+static AtkObject*
+gail_statusbar_ref_child (AtkObject *obj,
+ gint i)
+{
+ GList *children, *tmp_list;
+ AtkObject *accessible;
+ GtkWidget *widget;
+
+ g_return_val_if_fail ((i >= 0), NULL);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ return NULL;
+
+ children = gtk_container_get_children (GTK_CONTAINER (widget));
+ if (children == NULL)
+ return NULL;
+
+ tmp_list = g_list_nth (children, i);
+ if (!tmp_list)
+ {
+ g_list_free (children);
+ return NULL;
+ }
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
+
+ g_list_free (children);
+ g_object_ref (accessible);
+ return accessible;
+}
+
+static void
+gail_statusbar_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GailStatusbar *statusbar = GAIL_STATUSBAR (obj);
+ GtkWidget *label;
+
+ ATK_OBJECT_CLASS (gail_statusbar_parent_class)->initialize (obj, data);
+
+ /*
+ * We get notified of changes to the label
+ */
+ label = get_label_from_statusbar (GTK_WIDGET (data));
+ if (GTK_IS_LABEL (label))
+ {
+ gail_statusbar_init_textutil (statusbar, label);
+ }
+
+ obj->role = ATK_ROLE_STATUSBAR;
+
+}
+
+static gint
+gail_statusbar_notify (GObject *obj,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ AtkObject *atk_obj = ATK_OBJECT (user_data);
+ GtkLabel *label;
+ GailStatusbar *statusbar;
+
+ if (strcmp (pspec->name, "label") == 0)
+ {
+ const gchar* label_text;
+
+ label = GTK_LABEL (obj);
+
+ label_text = gtk_label_get_text (label);
+
+ statusbar = GAIL_STATUSBAR (atk_obj);
+ gail_text_util_text_setup (statusbar->textutil, label_text);
+
+ if (atk_obj->name == NULL)
+ {
+ /*
+ * The label has changed so notify a change in accessible-name
+ */
+ g_object_notify (G_OBJECT (atk_obj), "accessible-name");
+ }
+ /*
+ * The label is the only property which can be changed
+ */
+ g_signal_emit_by_name (atk_obj, "visible_data_changed");
+ }
+ return 1;
+}
+
+static void
+gail_statusbar_init_textutil (GailStatusbar *statusbar,
+ GtkWidget *label)
+{
+ const gchar *label_text;
+
+ statusbar->textutil = gail_text_util_new ();
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ gail_text_util_text_setup (statusbar->textutil, label_text);
+ g_signal_connect (label,
+ "notify",
+ (GCallback) gail_statusbar_notify,
+ statusbar);
+}
+
+static void
+gail_statusbar_finalize (GObject *object)
+{
+ GailStatusbar *statusbar = GAIL_STATUSBAR (object);
+
+ if (statusbar->textutil)
+ {
+ g_object_unref (statusbar->textutil);
+ }
+ G_OBJECT_CLASS (gail_statusbar_parent_class)->finalize (object);
+}
+
+/* atktext.h */
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_statusbar_get_text;
+ iface->get_character_at_offset = gail_statusbar_get_character_at_offset;
+ iface->get_text_before_offset = gail_statusbar_get_text_before_offset;
+ iface->get_text_at_offset = gail_statusbar_get_text_at_offset;
+ iface->get_text_after_offset = gail_statusbar_get_text_after_offset;
+ iface->get_character_count = gail_statusbar_get_character_count;
+ iface->get_character_extents = gail_statusbar_get_character_extents;
+ iface->get_offset_at_point = gail_statusbar_get_offset_at_point;
+ iface->get_run_attributes = gail_statusbar_get_run_attributes;
+ iface->get_default_attributes = gail_statusbar_get_default_attributes;
+}
+
+static gchar*
+gail_statusbar_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailStatusbar *statusbar;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL (label))
+ return NULL;
+
+ statusbar = GAIL_STATUSBAR (text);
+ if (!statusbar->textutil)
+ gail_statusbar_init_textutil (statusbar, label);
+
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+
+ if (label_text == NULL)
+ return NULL;
+ else
+ {
+ return gail_text_util_get_substring (statusbar->textutil,
+ start_pos, end_pos);
+ }
+}
+
+static gchar*
+gail_statusbar_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailStatusbar *statusbar;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get label */
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ statusbar = GAIL_STATUSBAR (text);
+ if (!statusbar->textutil)
+ gail_statusbar_init_textutil (statusbar, label);
+
+ return gail_text_util_get_text (statusbar->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)), GAIL_BEFORE_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_statusbar_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailStatusbar *statusbar;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Get label */
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ statusbar = GAIL_STATUSBAR (text);
+ if (!statusbar->textutil)
+ gail_statusbar_init_textutil (statusbar, label);
+
+ return gail_text_util_get_text (statusbar->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)), GAIL_AT_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_statusbar_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ GailStatusbar *statusbar;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return NULL;
+ }
+
+ /* Get label */
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ statusbar = GAIL_STATUSBAR (text);
+ if (!statusbar->textutil)
+ gail_statusbar_init_textutil (statusbar, label);
+
+ return gail_text_util_get_text (statusbar->textutil,
+ gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET,
+ boundary_type, offset, start_offset, end_offset);
+}
+
+static gint
+gail_statusbar_get_character_count (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return 0;
+
+ return g_utf8_strlen (gtk_label_get_text (GTK_LABEL (label)), -1);
+}
+
+static void
+gail_statusbar_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ PangoRectangle char_rect;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
+ pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
+
+ gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
+ x_layout, y_layout, x, y, width, height, coords);
+}
+
+static gint
+gail_statusbar_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ gint index, x_layout, y_layout;
+ const gchar *label_text;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return -1;
+
+ gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
+
+ index = gail_misc_get_index_at_point_in_layout (label,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ x_layout, y_layout, x, y, coords);
+ label_text = gtk_label_get_text (GTK_LABEL (label));
+ if (index == -1)
+ {
+ if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
+ return g_utf8_strlen (label_text, -1);
+
+ return index;
+ }
+ else
+ return g_utf8_pointer_to_offset (label_text, label_text + index);
+}
+
+static AtkAttributeSet*
+gail_statusbar_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkAttributeSet *at_set = NULL;
+ GtkJustification justify;
+ GtkTextDirection dir;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ /* Get values set for entire label, if any */
+ justify = gtk_label_get_justify (GTK_LABEL (label));
+ if (justify != GTK_JUSTIFY_CENTER)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_JUSTIFICATION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
+ }
+ dir = gtk_widget_get_direction (label);
+ if (dir == GTK_TEXT_DIR_RTL)
+ {
+ at_set = gail_misc_add_attribute (at_set,
+ ATK_TEXT_ATTR_DIRECTION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
+ }
+
+ at_set = gail_misc_layout_get_run_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ (gchar *) gtk_label_get_text (GTK_LABEL (label)),
+ offset,
+ start_offset,
+ end_offset);
+ return at_set;
+}
+
+static AtkAttributeSet*
+gail_statusbar_get_default_attributes (AtkText *text)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ AtkAttributeSet *at_set = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return NULL;
+
+ at_set = gail_misc_get_default_attributes (at_set,
+ gtk_label_get_layout (GTK_LABEL (label)),
+ widget);
+ return at_set;
+}
+
+static gunichar
+gail_statusbar_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GtkWidget *widget;
+ GtkWidget *label;
+ const gchar *string;
+ gchar *index;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return '\0';
+
+ label = get_label_from_statusbar (widget);
+
+ if (!GTK_IS_LABEL(label))
+ return '\0';
+ string = gtk_label_get_text (GTK_LABEL (label));
+ if (offset >= g_utf8_strlen (string, -1))
+ return '\0';
+ index = g_utf8_offset_to_pointer (string, offset);
+
+ return g_utf8_get_char (index);
+}
+
+static GtkWidget*
+get_label_from_statusbar (GtkWidget *statusbar)
+{
+ GtkWidget *message_area;
+ GList *children, *l;
+ GtkWidget *child;
+
+ message_area = gtk_statusbar_get_message_area (GTK_STATUSBAR (statusbar));
+
+ children = gtk_container_get_children (GTK_CONTAINER (message_area));
+ for (l = children; l; l = l->next)
+ {
+ child = l->data;
+ if (GTK_IS_LABEL (child))
+ break;
+ child = NULL;
+ }
+
+ g_list_free (children);
+
+ return child;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_STATUSBAR_H__
+#define __GAIL_STATUSBAR_H__
+
+#include "gailcontainer.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_STATUSBAR (gail_statusbar_get_type ())
+#define GAIL_STATUSBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_STATUSBAR, GailStatusbar))
+#define GAIL_STATUSBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_STATUSBAR, GailStatusbarClass))
+#define GAIL_IS_STATUSBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_STATUSBAR))
+#define GAIL_IS_STATUSBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_STATUSBAR))
+#define GAIL_STATUSBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_STATUSBAR, GailStatusbarClass))
+
+typedef struct _GailStatusbar GailStatusbar;
+typedef struct _GailStatusbarClass GailStatusbarClass;
+
+struct _GailStatusbar
+{
+ GailContainer parent;
+
+ GailTextUtil *textutil;
+};
+
+GType gail_statusbar_get_type (void);
+
+struct _GailStatusbarClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_STATUSBAR_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include "gailsubmenuitem.h"
+
+static void gail_sub_menu_item_class_init (GailSubMenuItemClass *klass);
+static void gail_sub_menu_item_init (GailSubMenuItem *item);
+static void gail_sub_menu_item_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static void atk_selection_interface_init (AtkSelectionIface *iface);
+static gboolean gail_sub_menu_item_add_selection (AtkSelection *selection,
+ gint i);
+static gboolean gail_sub_menu_item_clear_selection (AtkSelection *selection);
+static AtkObject* gail_sub_menu_item_ref_selection (AtkSelection *selection,
+ gint i);
+static gint gail_sub_menu_item_get_selection_count
+ (AtkSelection *selection);
+static gboolean gail_sub_menu_item_is_child_selected
+ (AtkSelection *selection,
+ gint i);
+static gboolean gail_sub_menu_item_remove_selection (AtkSelection *selection,
+ gint i);
+static gint menu_item_add_gtk (GtkContainer *container,
+ GtkWidget *widget);
+static gint menu_item_remove_gtk (GtkContainer *container,
+ GtkWidget *widget);
+
+G_DEFINE_TYPE_WITH_CODE (GailSubMenuItem, gail_sub_menu_item, GAIL_TYPE_MENU_ITEM,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
+
+static void
+gail_sub_menu_item_class_init (GailSubMenuItemClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ class->initialize = gail_sub_menu_item_real_initialize;
+}
+
+static void
+gail_sub_menu_item_init (GailSubMenuItem *item)
+{
+}
+
+static void
+gail_sub_menu_item_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkWidget *submenu;
+
+ ATK_OBJECT_CLASS (gail_sub_menu_item_parent_class)->initialize (obj, data);
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (data));
+ g_return_if_fail (submenu);
+
+ g_signal_connect (submenu,
+ "add",
+ G_CALLBACK (menu_item_add_gtk),
+ NULL);
+ g_signal_connect (submenu,
+ "remove",
+ G_CALLBACK (menu_item_remove_gtk),
+ NULL);
+
+ obj->role = ATK_ROLE_MENU;
+}
+
+AtkObject*
+gail_sub_menu_item_new (GtkWidget *widget)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), NULL);
+
+ object = g_object_new (GAIL_TYPE_SUB_MENU_ITEM, NULL);
+
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, widget);
+
+ return accessible;
+}
+
+static void
+atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ iface->add_selection = gail_sub_menu_item_add_selection;
+ iface->clear_selection = gail_sub_menu_item_clear_selection;
+ iface->ref_selection = gail_sub_menu_item_ref_selection;
+ iface->get_selection_count = gail_sub_menu_item_get_selection_count;
+ iface->is_child_selected = gail_sub_menu_item_is_child_selected;
+ iface->remove_selection = gail_sub_menu_item_remove_selection;
+ /*
+ * select_all_selection does not make sense for a submenu of a menu item
+ * so no implementation is provided.
+ */
+}
+
+static gboolean
+gail_sub_menu_item_add_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ GList *kids;
+ guint length;
+ GtkWidget *widget;
+ GtkWidget *submenu;
+ GtkWidget *child;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
+ shell = GTK_MENU_SHELL (submenu);
+ kids = gtk_container_get_children (GTK_CONTAINER (shell));
+ length = g_list_length (kids);
+ if (i < 0 || i > length)
+ {
+ g_list_free (kids);
+ return FALSE;
+ }
+
+ child = g_list_nth_data (kids, i);
+ g_list_free (kids);
+ g_return_val_if_fail (GTK_IS_MENU_ITEM(child), FALSE);
+ gtk_menu_shell_select_item (shell, GTK_WIDGET (child));
+ return TRUE;
+}
+
+static gboolean
+gail_sub_menu_item_clear_selection (AtkSelection *selection)
+{
+ GtkMenuShell *shell;
+ GtkWidget *widget;
+ GtkWidget *submenu;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
+ shell = GTK_MENU_SHELL (submenu);
+
+ gtk_menu_shell_deselect (shell);
+ return TRUE;
+}
+
+static AtkObject*
+gail_sub_menu_item_ref_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ AtkObject *obj;
+ GtkWidget *widget;
+ GtkWidget *submenu;
+ GtkWidget *item;
+
+ if (i != 0)
+ return NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), NULL);
+ shell = GTK_MENU_SHELL (submenu);
+
+ item = gtk_menu_shell_get_selected_item (shell);
+ if (item != NULL)
+ {
+ obj = gtk_widget_get_accessible (item);
+ g_object_ref (obj);
+ return obj;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static gint
+gail_sub_menu_item_get_selection_count (AtkSelection *selection)
+{
+ GtkMenuShell *shell;
+ GtkWidget *widget;
+ GtkWidget *submenu;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
+ shell = GTK_MENU_SHELL (submenu);
+
+ /*
+ * Identifies the currently selected menu item
+ */
+ if (gtk_menu_shell_get_selected_item (shell) == NULL)
+ return 0;
+ else
+ return 1;
+}
+
+static gboolean
+gail_sub_menu_item_is_child_selected (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ gint j;
+ GtkWidget *widget;
+ GtkWidget *submenu;
+ GtkWidget *item;
+ GList *kids;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
+ shell = GTK_MENU_SHELL (submenu);
+
+ item = gtk_menu_shell_get_selected_item (shell);
+ if (item == NULL)
+ return FALSE;
+
+ kids = gtk_container_get_children (GTK_CONTAINER (shell));
+ j = g_list_index (kids, item);
+ g_list_free (kids);
+
+ return (j==i);
+}
+
+static gboolean
+gail_sub_menu_item_remove_selection (AtkSelection *selection,
+ gint i)
+{
+ GtkMenuShell *shell;
+ GtkWidget *widget;
+ GtkWidget *submenu;
+ GtkWidget *item;
+
+ if (i != 0)
+ return FALSE;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
+ g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
+ shell = GTK_MENU_SHELL (submenu);
+
+ item = gtk_menu_shell_get_selected_item (shell);
+ if (item && gtk_menu_item_get_submenu (GTK_MENU_ITEM (item)))
+ {
+ /*
+ * Menu item contains a menu and it is the selected menu item
+ * so deselect it.
+ */
+ gtk_menu_shell_deselect (shell);
+ }
+ return TRUE;
+}
+
+static gint
+menu_item_add_gtk (GtkContainer *container,
+ GtkWidget *widget)
+{
+ GtkWidget *parent_widget;
+ AtkObject *atk_parent;
+ AtkObject *atk_child;
+ GailContainer *gail_container;
+ gint index;
+
+ g_return_val_if_fail (GTK_IS_MENU (container), 1);
+
+ parent_widget = gtk_menu_get_attach_widget (GTK_MENU (container));
+ if (GTK_IS_MENU_ITEM (parent_widget))
+ {
+ atk_parent = gtk_widget_get_accessible (parent_widget);
+ atk_child = gtk_widget_get_accessible (widget);
+
+ gail_container = GAIL_CONTAINER (atk_parent);
+ g_object_notify (G_OBJECT (atk_child), "accessible_parent");
+
+ g_list_free (gail_container->children);
+ gail_container->children = gtk_container_get_children (container);
+ index = g_list_index (gail_container->children, widget);
+ g_signal_emit_by_name (atk_parent, "children_changed::add",
+ index, atk_child, NULL);
+ }
+ return 1;
+}
+
+static gint
+menu_item_remove_gtk (GtkContainer *container,
+ GtkWidget *widget)
+{
+ GtkWidget *parent_widget;
+ AtkObject *atk_parent;
+ AtkObject *atk_child;
+ GailContainer *gail_container;
+ AtkPropertyValues values = { NULL };
+ gint index;
+ gint list_length;
+
+ g_return_val_if_fail (GTK_IS_MENU (container), 1);
+
+ parent_widget = gtk_menu_get_attach_widget (GTK_MENU (container));
+ if (GTK_IS_MENU_ITEM (parent_widget))
+ {
+ atk_parent = gtk_widget_get_accessible (parent_widget);
+ atk_child = gtk_widget_get_accessible (widget);
+
+ gail_container = GAIL_CONTAINER (atk_parent);
+ g_value_init (&values.old_value, G_TYPE_POINTER);
+ g_value_set_pointer (&values.old_value, atk_parent);
+ values.property_name = "accessible-parent";
+ g_signal_emit_by_name (atk_child,
+ "property_change::accessible-parent", &values, NULL);
+
+ index = g_list_index (gail_container->children, widget);
+ list_length = g_list_length (gail_container->children);
+ g_list_free (gail_container->children);
+ gail_container->children = gtk_container_get_children (container);
+ if (index >= 0 && index <= list_length)
+ g_signal_emit_by_name (atk_parent, "children_changed::remove",
+ index, atk_child, NULL);
+ }
+ return 1;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_SUB_MENU_ITEM_H__
+#define __GAIL_SUB_MENU_ITEM_H__
+
+#include "gailmenuitem.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_SUB_MENU_ITEM (gail_sub_menu_item_get_type ())
+#define GAIL_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SUB_MENU_ITEM, GailSubMenuItem))
+#define GAIL_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SUB_MENU_ITEM, GailSubMenuItemClass))
+#define GAIL_IS_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SUB_MENU_ITEM))
+#define GAIL_IS_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SUB_MENU_ITEM))
+#define GAIL_SUB_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SUB_MENU_ITEM, GailSubMenuItemClass))
+
+typedef struct _GailSubMenuItem GailSubMenuItem;
+typedef struct _GailSubMenuItemClass GailSubMenuItemClass;
+
+struct _GailSubMenuItem
+{
+ GailMenuItem parent;
+
+};
+
+GType gail_sub_menu_item_get_type (void);
+
+struct _GailSubMenuItemClass
+{
+ GailMenuItemClass parent_class;
+};
+
+AtkObject* gail_sub_menu_item_new (GtkWidget *widget);
+
+G_END_DECLS
+
+#endif /* __GAIL_SUB_MENU_ITEM_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailtextcell.h"
+#include "gailcontainercell.h"
+#include "gailcellparent.h"
+#include <libgail-util/gailmisc.h>
+#include "gail-private-macros.h"
+
+static void gail_text_cell_class_init (GailTextCellClass *klass);
+static void gail_text_cell_init (GailTextCell *text_cell);
+static void gail_text_cell_finalize (GObject *object);
+
+static const gchar* gail_text_cell_get_name (AtkObject *atk_obj);
+
+static void atk_text_interface_init (AtkTextIface *iface);
+
+/* atktext.h */
+
+static gchar* gail_text_cell_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos);
+static gunichar gail_text_cell_get_character_at_offset (AtkText *text,
+ gint offset);
+static gchar* gail_text_cell_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_text_cell_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_text_cell_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gint gail_text_cell_get_character_count (AtkText *text);
+static gint gail_text_cell_get_caret_offset (AtkText *text);
+static gboolean gail_text_cell_set_caret_offset (AtkText *text,
+ gint offset);
+static void gail_text_cell_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static gint gail_text_cell_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static AtkAttributeSet* gail_text_cell_get_run_attributes
+ (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet* gail_text_cell_get_default_attributes
+ (AtkText *text);
+
+static PangoLayout* create_pango_layout (GtkCellRendererText *gtk_renderer,
+ GtkWidget *widget);
+static void add_attr (PangoAttrList *attr_list,
+ PangoAttribute *attr);
+
+/* Misc */
+
+static gboolean gail_text_cell_update_cache (GailRendererCell *cell,
+ gboolean emit_change_signal);
+
+gchar *gail_text_cell_property_list[] = {
+ /* Set font_desc first since it resets other values if it is NULL */
+ "font_desc",
+
+ "attributes",
+ "background-gdk",
+ "editable",
+ "family",
+ "foreground-gdk",
+ "rise",
+ "scale",
+ "size",
+ "size-points",
+ "stretch",
+ "strikethrough",
+ "style",
+ "text",
+ "underline",
+ "variant",
+ "weight",
+
+ /* Also need the sets */
+ "background-set",
+ "editable-set",
+ "family-set",
+ "foreground-set",
+ "rise-set",
+ "scale-set",
+ "size-set",
+ "stretch-set",
+ "strikethrough-set",
+ "style-set",
+ "underline-set",
+ "variant-set",
+ "weight-set",
+ NULL
+};
+
+G_DEFINE_TYPE_WITH_CODE (GailTextCell, gail_text_cell, GAIL_TYPE_RENDERER_CELL,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
+
+static void
+gail_text_cell_class_init (GailTextCellClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
+ GailRendererCellClass *renderer_cell_class = GAIL_RENDERER_CELL_CLASS (klass);
+
+ renderer_cell_class->update_cache = gail_text_cell_update_cache;
+ renderer_cell_class->property_list = gail_text_cell_property_list;
+
+ atk_object_class->get_name = gail_text_cell_get_name;
+
+ gobject_class->finalize = gail_text_cell_finalize;
+}
+
+/* atktext.h */
+
+static void
+gail_text_cell_init (GailTextCell *text_cell)
+{
+ text_cell->cell_text = NULL;
+ text_cell->caret_pos = 0;
+ text_cell->cell_length = 0;
+ text_cell->textutil = gail_text_util_new ();
+ atk_state_set_add_state (GAIL_CELL (text_cell)->state_set,
+ ATK_STATE_SINGLE_LINE);
+}
+
+AtkObject*
+gail_text_cell_new (void)
+{
+ GObject *object;
+ AtkObject *atk_object;
+ GailRendererCell *cell;
+
+ object = g_object_new (GAIL_TYPE_TEXT_CELL, NULL);
+
+ g_return_val_if_fail (object != NULL, NULL);
+
+ atk_object = ATK_OBJECT (object);
+ atk_object->role = ATK_ROLE_TABLE_CELL;
+
+ cell = GAIL_RENDERER_CELL(object);
+
+ cell->renderer = gtk_cell_renderer_text_new ();
+ g_object_ref_sink (cell->renderer);
+ return atk_object;
+}
+
+static void
+gail_text_cell_finalize (GObject *object)
+{
+ GailTextCell *text_cell = GAIL_TEXT_CELL (object);
+
+ g_object_unref (text_cell->textutil);
+ g_free (text_cell->cell_text);
+
+ G_OBJECT_CLASS (gail_text_cell_parent_class)->finalize (object);
+}
+
+static const gchar*
+gail_text_cell_get_name (AtkObject *atk_obj)
+{
+ if (atk_obj->name)
+ return atk_obj->name;
+ else
+ {
+ GailTextCell *text_cell = GAIL_TEXT_CELL (atk_obj);
+
+ return text_cell->cell_text;
+ }
+}
+
+static gboolean
+gail_text_cell_update_cache (GailRendererCell *cell,
+ gboolean emit_change_signal)
+{
+ GailTextCell *text_cell = GAIL_TEXT_CELL (cell);
+ AtkObject *obj = ATK_OBJECT (cell);
+ gboolean rv = FALSE;
+ gint temp_length;
+ gchar *new_cache;
+
+ g_object_get (G_OBJECT (cell->renderer), "text", &new_cache, NULL);
+
+ if (text_cell->cell_text)
+ {
+ /*
+ * If the new value is NULL and the old value isn't NULL, then the
+ * value has changed.
+ */
+ if (new_cache == NULL ||
+ strcmp (text_cell->cell_text, new_cache))
+ {
+ g_free (text_cell->cell_text);
+ temp_length = text_cell->cell_length;
+ text_cell->cell_text = NULL;
+ text_cell->cell_length = 0;
+ if (emit_change_signal)
+ {
+ g_signal_emit_by_name (cell, "text_changed::delete", 0, temp_length);
+ if (obj->name == NULL)
+ g_object_notify (G_OBJECT (obj), "accessible-name");
+ }
+ if (new_cache)
+ rv = TRUE;
+ }
+ }
+ else
+ rv = TRUE;
+
+ if (rv)
+ {
+ if (new_cache == NULL)
+ {
+ text_cell->cell_text = g_strdup ("");
+ text_cell->cell_length = 0;
+ }
+ else
+ {
+ text_cell->cell_text = g_strdup (new_cache);
+ text_cell->cell_length = g_utf8_strlen (new_cache, -1);
+ }
+ }
+
+ g_free (new_cache);
+ gail_text_util_text_setup (text_cell->textutil, text_cell->cell_text);
+
+ if (rv)
+ {
+ if (emit_change_signal)
+ {
+ g_signal_emit_by_name (cell, "text_changed::insert",
+ 0, text_cell->cell_length);
+
+ if (obj->name == NULL)
+ g_object_notify (G_OBJECT (obj), "accessible-name");
+ }
+ }
+ return rv;
+}
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_text_cell_get_text;
+ iface->get_character_at_offset = gail_text_cell_get_character_at_offset;
+ iface->get_text_before_offset = gail_text_cell_get_text_before_offset;
+ iface->get_text_at_offset = gail_text_cell_get_text_at_offset;
+ iface->get_text_after_offset = gail_text_cell_get_text_after_offset;
+ iface->get_character_count = gail_text_cell_get_character_count;
+ iface->get_caret_offset = gail_text_cell_get_caret_offset;
+ iface->set_caret_offset = gail_text_cell_set_caret_offset;
+ iface->get_run_attributes = gail_text_cell_get_run_attributes;
+ iface->get_default_attributes = gail_text_cell_get_default_attributes;
+ iface->get_character_extents = gail_text_cell_get_character_extents;
+ iface->get_offset_at_point = gail_text_cell_get_offset_at_point;
+}
+
+static gchar*
+gail_text_cell_get_text (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ if (GAIL_TEXT_CELL (text)->cell_text)
+ return gail_text_util_get_substring (GAIL_TEXT_CELL (text)->textutil,
+ start_pos, end_pos);
+ else
+ return g_strdup ("");
+}
+
+static gchar*
+gail_text_cell_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ return gail_text_util_get_text (GAIL_TEXT_CELL (text)->textutil,
+ NULL, GAIL_BEFORE_OFFSET, boundary_type, offset, start_offset,
+ end_offset);
+}
+
+static gchar*
+gail_text_cell_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ return gail_text_util_get_text (GAIL_TEXT_CELL (text)->textutil,
+ NULL, GAIL_AT_OFFSET, boundary_type, offset, start_offset, end_offset);
+}
+
+static gchar*
+gail_text_cell_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ return gail_text_util_get_text (GAIL_TEXT_CELL (text)->textutil,
+ NULL, GAIL_AFTER_OFFSET, boundary_type, offset, start_offset,
+ end_offset);
+}
+
+static gint
+gail_text_cell_get_character_count (AtkText *text)
+{
+ if (GAIL_TEXT_CELL (text)->cell_text != NULL)
+ return GAIL_TEXT_CELL (text)->cell_length;
+ else
+ return 0;
+}
+
+static gint
+gail_text_cell_get_caret_offset (AtkText *text)
+{
+ return GAIL_TEXT_CELL (text)->caret_pos;
+}
+
+static gboolean
+gail_text_cell_set_caret_offset (AtkText *text,
+ gint offset)
+{
+ GailTextCell *text_cell = GAIL_TEXT_CELL (text);
+
+ if (text_cell->cell_text == NULL)
+ return FALSE;
+ else
+ {
+
+ /* Only set the caret within the bounds and if it is to a new position. */
+ if (offset >= 0 &&
+ offset <= text_cell->cell_length &&
+ offset != text_cell->caret_pos)
+ {
+ text_cell->caret_pos = offset;
+
+ /* emit the signal */
+ g_signal_emit_by_name (text, "text_caret_moved", offset);
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+}
+
+static AtkAttributeSet*
+gail_text_cell_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GailRendererCell *gail_renderer;
+ GtkCellRendererText *gtk_renderer;
+ AtkAttributeSet *attrib_set = NULL;
+ PangoLayout *layout;
+ AtkObject *parent;
+ GtkWidget *widget;
+ gchar *renderer_text;
+
+ gail_renderer = GAIL_RENDERER_CELL (text);
+ gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
+
+ parent = atk_object_get_parent (ATK_OBJECT (text));
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ parent = atk_object_get_parent (parent);
+ g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), NULL);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
+ layout = create_pango_layout (gtk_renderer, widget),
+ g_object_get (gtk_renderer, "text", &renderer_text, NULL);
+ attrib_set = gail_misc_layout_get_run_attributes (attrib_set,
+ layout,
+ renderer_text,
+ offset,
+ start_offset,
+ end_offset);
+ g_free (renderer_text);
+ g_object_unref (G_OBJECT (layout));
+
+ return attrib_set;
+}
+
+static AtkAttributeSet*
+gail_text_cell_get_default_attributes (AtkText *text)
+{
+ GailRendererCell *gail_renderer;
+ GtkCellRendererText *gtk_renderer;
+ AtkAttributeSet *attrib_set = NULL;
+ PangoLayout *layout;
+ AtkObject *parent;
+ GtkWidget *widget;
+
+ gail_renderer = GAIL_RENDERER_CELL (text);
+ gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
+
+ parent = atk_object_get_parent (ATK_OBJECT (text));
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ parent = atk_object_get_parent (parent);
+ g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), NULL);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
+ layout = create_pango_layout (gtk_renderer, widget),
+
+ attrib_set = gail_misc_get_default_attributes (attrib_set,
+ layout,
+ widget);
+ g_object_unref (G_OBJECT (layout));
+ return attrib_set;
+}
+
+/*
+ * This function is used by gail_text_cell_get_offset_at_point()
+ * and gail_text_cell_get_character_extents(). There is no
+ * cached PangoLayout for gailtextcell so we must create a temporary
+ * one using this function.
+ */
+static PangoLayout*
+create_pango_layout(GtkCellRendererText *gtk_renderer,
+ GtkWidget *widget)
+{
+ GdkRGBA *foreground_rgba;
+ PangoAttrList *attr_list, *attributes;
+ PangoLayout *layout;
+ PangoUnderline uline, underline;
+ PangoFontMask mask;
+ PangoFontDescription *font_desc;
+ gboolean foreground_set, strikethrough_set, strikethrough;
+ gboolean scale_set, underline_set, rise_set;
+ gchar *renderer_text;
+ gdouble scale;
+ gint rise;
+
+ g_object_get (gtk_renderer,
+ "text", &renderer_text,
+ "attributes", &attributes,
+ "foreground-set", &foreground_set,
+ "foreground-rgba", &foreground_rgba,
+ "strikethrough-set", &strikethrough_set,
+ "strikethrough", &strikethrough,
+ "font-desc", &font_desc,
+ "scale-set", &scale_set,
+ "scale", &scale,
+ "underline-set", &underline_set,
+ "underline", &underline,
+ "rise-set", &rise_set,
+ "rise", &rise,
+ NULL);
+
+ layout = gtk_widget_create_pango_layout (widget, renderer_text);
+
+ if (attributes)
+ attr_list = pango_attr_list_copy (attributes);
+ else
+ attr_list = pango_attr_list_new ();
+
+ if (foreground_set)
+ {
+ add_attr (attr_list, pango_attr_foreground_new (foreground_rgba->red * 65535,
+ foreground_rgba->green * 65535,
+ foreground_rgba->blue * 65535));
+ }
+
+ if (strikethrough_set)
+ add_attr (attr_list,
+ pango_attr_strikethrough_new (strikethrough));
+
+ mask = pango_font_description_get_set_fields (font_desc);
+
+ if (mask & PANGO_FONT_MASK_FAMILY)
+ add_attr (attr_list,
+ pango_attr_family_new (pango_font_description_get_family (font_desc)));
+
+ if (mask & PANGO_FONT_MASK_STYLE)
+ add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (font_desc)));
+
+ if (mask & PANGO_FONT_MASK_VARIANT)
+ add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (font_desc)));
+
+ if (mask & PANGO_FONT_MASK_WEIGHT)
+ add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (font_desc)));
+
+ if (mask & PANGO_FONT_MASK_STRETCH)
+ add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (font_desc)));
+
+ if (mask & PANGO_FONT_MASK_SIZE)
+ add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (font_desc)));
+
+ if (scale_set && scale != 1.0)
+ add_attr (attr_list, pango_attr_scale_new (scale));
+
+ if (underline_set)
+ uline = underline;
+ else
+ uline = PANGO_UNDERLINE_NONE;
+
+ if (uline != PANGO_UNDERLINE_NONE)
+ add_attr (attr_list,
+ pango_attr_underline_new (underline));
+
+ if (rise_set)
+ add_attr (attr_list, pango_attr_rise_new (rise));
+
+ pango_layout_set_attributes (layout, attr_list);
+ pango_layout_set_width (layout, -1);
+ pango_attr_list_unref (attr_list);
+
+ pango_font_description_free (font_desc);
+ pango_attr_list_unref (attributes);
+ g_free (renderer_text);
+ gdk_rgba_free (foreground_rgba);
+
+ return layout;
+}
+
+static void
+add_attr (PangoAttrList *attr_list,
+ PangoAttribute *attr)
+{
+ attr->start_index = 0;
+ attr->end_index = G_MAXINT;
+ pango_attr_list_insert (attr_list, attr);
+}
+
+static void
+gail_text_cell_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GailRendererCell *gail_renderer;
+ GtkRequisition min_size;
+ GtkCellRendererText *gtk_renderer;
+ GdkRectangle rendered_rect;
+ GtkWidget *widget;
+ AtkObject *parent;
+ PangoRectangle char_rect;
+ PangoLayout *layout;
+ gchar *renderer_text;
+ gfloat xalign, yalign;
+ gint x_offset, y_offset, index;
+ gint xpad, ypad;
+
+ if (!GAIL_TEXT_CELL (text)->cell_text)
+ {
+ *x = *y = *height = *width = 0;
+ return;
+ }
+ if (offset < 0 || offset >= GAIL_TEXT_CELL (text)->cell_length)
+ {
+ *x = *y = *height = *width = 0;
+ return;
+ }
+ gail_renderer = GAIL_RENDERER_CELL (text);
+ gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
+ /*
+ * Thus would be inconsistent with the cache
+ */
+ g_object_get (gtk_renderer, "text", &renderer_text, NULL);
+ if (text == NULL)
+ {
+ g_free (renderer_text);
+ return;
+ }
+
+ parent = atk_object_get_parent (ATK_OBJECT (text));
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ parent = atk_object_get_parent (parent);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
+ g_return_if_fail (GAIL_IS_CELL_PARENT (parent));
+ gail_cell_parent_get_cell_area (GAIL_CELL_PARENT (parent), GAIL_CELL (text),
+ &rendered_rect);
+
+ gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
+ widget,
+ &min_size, NULL);
+
+ gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+ xalign = 1.0 - xalign;
+ x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
+ y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));
+
+ layout = create_pango_layout (gtk_renderer, widget);
+
+ index = g_utf8_offset_to_pointer (renderer_text, offset) - renderer_text;
+ pango_layout_index_to_pos (layout, index, &char_rect);
+
+ gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);
+ gail_misc_get_extents_from_pango_rectangle (widget,
+ &char_rect,
+ x_offset + rendered_rect.x + xpad,
+ y_offset + rendered_rect.y + ypad,
+ x, y, width, height, coords);
+
+ g_free (renderer_text);
+ g_object_unref (layout);
+
+ return;
+}
+
+static gint
+gail_text_cell_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ AtkObject *parent;
+ GailRendererCell *gail_renderer;
+ GtkCellRendererText *gtk_renderer;
+ GtkRequisition min_size;
+ GtkWidget *widget;
+ GdkRectangle rendered_rect;
+ PangoLayout *layout;
+ gchar *renderer_text;
+ gfloat xalign, yalign;
+ gint x_offset, y_offset, index;
+ gint xpad, ypad;
+
+ if (!GAIL_TEXT_CELL (text)->cell_text)
+ return -1;
+
+ gail_renderer = GAIL_RENDERER_CELL (text);
+ gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
+ parent = atk_object_get_parent (ATK_OBJECT (text));
+
+ g_object_get (gtk_renderer, "text", &renderer_text, NULL);
+ if (text == NULL)
+ {
+ g_free (renderer_text);
+ return -1;
+ }
+
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ parent = atk_object_get_parent (parent);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
+
+ g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), -1);
+ gail_cell_parent_get_cell_area (GAIL_CELL_PARENT (parent), GAIL_CELL (text),
+ &rendered_rect);
+
+ gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
+ widget,
+ &min_size, NULL);
+ gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+ xalign = 1.0 - xalign;
+ x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
+ y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));
+
+ layout = create_pango_layout (gtk_renderer, widget);
+
+ gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);
+ index = gail_misc_get_index_at_point_in_layout (widget, layout,
+ x_offset + rendered_rect.x + xpad,
+ y_offset + rendered_rect.y + ypad,
+ x, y, coords);
+ g_object_unref (layout);
+ if (index == -1)
+ {
+ if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
+ {
+ glong length;
+
+ length = g_utf8_strlen (renderer_text, -1);
+ g_free (renderer_text);
+
+ return length;
+ }
+
+ g_free (renderer_text);
+
+ return index;
+ }
+ else
+ {
+ glong offset;
+
+ offset = g_utf8_pointer_to_offset (renderer_text,
+ renderer_text + index);
+ g_free (renderer_text);
+
+ return offset;
+ }
+}
+
+static gunichar
+gail_text_cell_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ gchar *index;
+ gchar *string;
+
+ string = GAIL_TEXT_CELL(text)->cell_text;
+
+ if (!string)
+ return '\0';
+
+ if (offset >= g_utf8_strlen (string, -1))
+ return '\0';
+
+ index = g_utf8_offset_to_pointer (string, offset);
+
+ return g_utf8_get_char (index);
+}
+
--- /dev/null
+/* GAIL - The GNOME Accessibility Enabling Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_TEXT_CELL_H__
+#define __GAIL_TEXT_CELL_H__
+
+#include <atk/atk.h>
+#include "gailrenderercell.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_TEXT_CELL (gail_text_cell_get_type ())
+#define GAIL_TEXT_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TEXT_CELL, GailTextCell))
+#define GAIL_TEXT_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TEXT_CELL, GailTextCellClass))
+#define GAIL_IS_TEXT_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TEXT_CELL))
+#define GAIL_IS_TEXT_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TEXT_CELL))
+#define GAIL_TEXT_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TEXT_CELL, GailTextCellClass))
+
+typedef struct _GailTextCell GailTextCell;
+typedef struct _GailTextCellClass GailTextCellClass;
+
+struct _GailTextCell
+{
+ GailRendererCell parent;
+ GailTextUtil *textutil;
+ gchar *cell_text;
+ gint caret_pos;
+ gint cell_length;
+};
+
+GType gail_text_cell_get_type (void);
+
+struct _GailTextCellClass
+{
+ GailRendererCellClass parent_class;
+};
+
+AtkObject *gail_text_cell_new (void);
+
+G_END_DECLS
+
+#endif /* __GAIL_TREE_VIEW_TEXT_CELL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include "gailtextview.h"
+#include <libgail-util/gailmisc.h>
+
+static void gail_text_view_class_init (GailTextViewClass *klass);
+static void gail_text_view_init (GailTextView *text_view);
+
+static void gail_text_view_real_initialize (AtkObject *obj,
+ gpointer data);
+static void gail_text_view_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+
+static void gail_text_view_finalize (GObject *object);
+
+static void atk_text_interface_init (AtkTextIface *iface);
+
+/* atkobject.h */
+
+static AtkStateSet* gail_text_view_ref_state_set (AtkObject *accessible);
+
+/* atktext.h */
+
+static gchar* gail_text_view_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_text_view_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_text_view_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset);
+static gchar* gail_text_view_get_text (AtkText*text,
+ gint start_offset,
+ gint end_offset);
+static gunichar gail_text_view_get_character_at_offset (AtkText *text,
+ gint offset);
+static gint gail_text_view_get_character_count (AtkText *text);
+static gint gail_text_view_get_caret_offset (AtkText *text);
+static gboolean gail_text_view_set_caret_offset (AtkText *text,
+ gint offset);
+static gint gail_text_view_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+static gint gail_text_view_get_n_selections (AtkText *text);
+static gchar* gail_text_view_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_offset,
+ gint *end_offset);
+static gboolean gail_text_view_add_selection (AtkText *text,
+ gint start_offset,
+ gint end_offset);
+static gboolean gail_text_view_remove_selection (AtkText *text,
+ gint selection_num);
+static gboolean gail_text_view_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_offset,
+ gint end_offset);
+static void gail_text_view_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+static AtkAttributeSet * gail_text_view_get_run_attributes
+ (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static AtkAttributeSet * gail_text_view_get_default_attributes
+ (AtkText *text);
+/* atkeditabletext.h */
+
+static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
+static gboolean gail_text_view_set_run_attributes (AtkEditableText *text,
+ AtkAttributeSet *attrib_set,
+ gint start_offset,
+ gint end_offset);
+static void gail_text_view_set_text_contents (AtkEditableText *text,
+ const gchar *string);
+static void gail_text_view_insert_text (AtkEditableText *text,
+ const gchar *string,
+ gint length,
+ gint *position);
+static void gail_text_view_copy_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+static void gail_text_view_cut_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+static void gail_text_view_delete_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos);
+static void gail_text_view_paste_text (AtkEditableText *text,
+ gint position);
+static void gail_text_view_paste_received (GtkClipboard *clipboard,
+ const gchar *text,
+ gpointer data);
+/* AtkStreamableContent */
+static void atk_streamable_content_interface_init (AtkStreamableContentIface *iface);
+static gint gail_streamable_content_get_n_mime_types (AtkStreamableContent *streamable);
+static const gchar* gail_streamable_content_get_mime_type (AtkStreamableContent *streamable,
+ gint i);
+static GIOChannel* gail_streamable_content_get_stream (AtkStreamableContent *streamable,
+ const gchar *mime_type);
+/* getURI requires atk-1.12.0 or later
+static void gail_streamable_content_get_uri (AtkStreamableContent *streamable);
+*/
+
+/* Callbacks */
+
+static void _gail_text_view_insert_text_cb (GtkTextBuffer *buffer,
+ GtkTextIter *arg1,
+ gchar *arg2,
+ gint arg3,
+ gpointer user_data);
+static void _gail_text_view_delete_range_cb (GtkTextBuffer *buffer,
+ GtkTextIter *arg1,
+ GtkTextIter *arg2,
+ gpointer user_data);
+static void _gail_text_view_changed_cb (GtkTextBuffer *buffer,
+ gpointer user_data);
+static void _gail_text_view_mark_set_cb (GtkTextBuffer *buffer,
+ GtkTextIter *arg1,
+ GtkTextMark *arg2,
+ gpointer user_data);
+static gchar* get_text_near_offset (AtkText *text,
+ GailOffsetType function,
+ AtkTextBoundary boundary_type,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+static gint get_insert_offset (GtkTextBuffer *buffer);
+static gint get_selection_bound (GtkTextBuffer *buffer);
+static void emit_text_caret_moved (GailTextView *gail_text_view,
+ gint insert_offset);
+static gint insert_idle_handler (gpointer data);
+
+typedef struct _GailTextViewPaste GailTextViewPaste;
+
+struct _GailTextViewPaste
+{
+ GtkTextBuffer* buffer;
+ gint position;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GailTextView, gail_text_view, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_STREAMABLE_CONTENT, atk_streamable_content_interface_init))
+
+static void
+gail_text_view_class_init (GailTextViewClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GailWidgetClass *widget_class;
+
+ widget_class = (GailWidgetClass*)klass;
+
+ gobject_class->finalize = gail_text_view_finalize;
+
+ class->ref_state_set = gail_text_view_ref_state_set;
+ class->initialize = gail_text_view_real_initialize;
+
+ widget_class->notify_gtk = gail_text_view_real_notify_gtk;
+}
+
+static void
+gail_text_view_init (GailTextView *text_view)
+{
+ text_view->textutil = NULL;
+ text_view->signal_name = NULL;
+ text_view->previous_insert_offset = -1;
+ text_view->previous_selection_bound = -1;
+ text_view->insert_notify_handler = 0;
+}
+
+static void
+setup_buffer (GtkTextView *view,
+ GailTextView *gail_view)
+{
+ GtkTextBuffer *buffer;
+
+ buffer = gtk_text_view_get_buffer (view);
+
+ if (gail_view->textutil)
+ g_object_unref (gail_view->textutil);
+
+ gail_view->textutil = gail_text_util_new ();
+ gail_text_util_buffer_setup (gail_view->textutil, buffer);
+
+ /* Set up signal callbacks */
+ g_signal_connect_data (buffer, "insert-text",
+ (GCallback) _gail_text_view_insert_text_cb, view, NULL, 0);
+ g_signal_connect_data (buffer, "delete-range",
+ (GCallback) _gail_text_view_delete_range_cb, view, NULL, 0);
+ g_signal_connect_data (buffer, "mark-set",
+ (GCallback) _gail_text_view_mark_set_cb, view, NULL, 0);
+ g_signal_connect_data (buffer, "changed",
+ (GCallback) _gail_text_view_changed_cb, view, NULL, 0);
+
+}
+
+static void
+gail_text_view_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkTextView *view;
+ GailTextView *gail_view;
+
+ ATK_OBJECT_CLASS (gail_text_view_parent_class)->initialize (obj, data);
+
+ view = GTK_TEXT_VIEW (data);
+
+ gail_view = GAIL_TEXT_VIEW (obj);
+ setup_buffer (view, gail_view);
+
+ obj->role = ATK_ROLE_TEXT;
+
+}
+
+static void
+gail_text_view_finalize (GObject *object)
+{
+ GailTextView *text_view = GAIL_TEXT_VIEW (object);
+
+ g_object_unref (text_view->textutil);
+ if (text_view->insert_notify_handler)
+ g_source_remove (text_view->insert_notify_handler);
+
+ G_OBJECT_CLASS (gail_text_view_parent_class)->finalize (object);
+}
+
+static void
+gail_text_view_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ if (!strcmp (pspec->name, "editable"))
+ {
+ AtkObject *atk_obj;
+ gboolean editable;
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj));
+ editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (obj));
+ atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE,
+ editable);
+ }
+ else if (!strcmp (pspec->name, "buffer"))
+ {
+ AtkObject *atk_obj;
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj));
+ setup_buffer (GTK_TEXT_VIEW (obj), GAIL_TEXT_VIEW (atk_obj));
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_text_view_parent_class)->notify_gtk (obj, pspec);
+}
+
+/* atkobject.h */
+
+static AtkStateSet*
+gail_text_view_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GtkTextView *text_view;
+ GtkWidget *widget;
+
+ state_set = ATK_OBJECT_CLASS (gail_text_view_parent_class)->ref_state_set (accessible);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ return state_set;
+
+ text_view = GTK_TEXT_VIEW (widget);
+
+ if (gtk_text_view_get_editable (text_view))
+ atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
+ atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
+
+ return state_set;
+}
+
+/* atktext.h */
+
+static void
+atk_text_interface_init (AtkTextIface *iface)
+{
+ iface->get_text = gail_text_view_get_text;
+ iface->get_text_after_offset = gail_text_view_get_text_after_offset;
+ iface->get_text_at_offset = gail_text_view_get_text_at_offset;
+ iface->get_text_before_offset = gail_text_view_get_text_before_offset;
+ iface->get_character_at_offset = gail_text_view_get_character_at_offset;
+ iface->get_character_count = gail_text_view_get_character_count;
+ iface->get_caret_offset = gail_text_view_get_caret_offset;
+ iface->set_caret_offset = gail_text_view_set_caret_offset;
+ iface->get_offset_at_point = gail_text_view_get_offset_at_point;
+ iface->get_character_extents = gail_text_view_get_character_extents;
+ iface->get_n_selections = gail_text_view_get_n_selections;
+ iface->get_selection = gail_text_view_get_selection;
+ iface->add_selection = gail_text_view_add_selection;
+ iface->remove_selection = gail_text_view_remove_selection;
+ iface->set_selection = gail_text_view_set_selection;
+ iface->get_run_attributes = gail_text_view_get_run_attributes;
+ iface->get_default_attributes = gail_text_view_get_default_attributes;
+}
+
+static gchar*
+gail_text_view_get_text (AtkText *text,
+ gint start_offset,
+ gint end_offset)
+{
+ GtkTextView *view;
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+ gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
+
+ return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+}
+
+static gchar*
+gail_text_view_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ return get_text_near_offset (text, GAIL_AFTER_OFFSET,
+ boundary_type, offset,
+ start_offset, end_offset);
+}
+
+static gchar*
+gail_text_view_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ return get_text_near_offset (text, GAIL_AT_OFFSET,
+ boundary_type, offset,
+ start_offset, end_offset);
+}
+
+static gchar*
+gail_text_view_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ return get_text_near_offset (text, GAIL_BEFORE_OFFSET,
+ boundary_type, offset,
+ start_offset, end_offset);
+}
+
+static gunichar
+gail_text_view_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GtkWidget *widget;
+ GtkTextIter start, end;
+ GtkTextBuffer *buffer;
+ gchar *string;
+ gunichar unichar;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ return '\0';
+
+ buffer = GAIL_TEXT_VIEW (text)->textutil->buffer;
+ if (offset >= gtk_text_buffer_get_char_count (buffer))
+ return '\0';
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
+ end = start;
+ gtk_text_iter_forward_char (&end);
+ string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
+ unichar = g_utf8_get_char (string);
+ g_free(string);
+ return unichar;
+}
+
+static gint
+gail_text_view_get_character_count (AtkText *text)
+{
+ GtkTextView *view;
+ GtkTextBuffer *buffer;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+ return gtk_text_buffer_get_char_count (buffer);
+}
+
+static gint
+gail_text_view_get_caret_offset (AtkText *text)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ view = GTK_TEXT_VIEW (widget);
+ return get_insert_offset (gtk_text_view_get_buffer (view));
+}
+
+static gboolean
+gail_text_view_set_caret_offset (AtkText *text,
+ gint offset)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter pos_itr;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, offset);
+ gtk_text_buffer_place_cursor (buffer, &pos_itr);
+ gtk_text_view_scroll_to_iter (view, &pos_itr, 0, FALSE, 0, 0);
+ return TRUE;
+}
+
+static gint
+gail_text_view_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GtkTextView *view;
+ GtkTextIter loc_itr;
+ gint x_widget, y_widget, x_window, y_window, buff_x, buff_y;
+ GtkWidget *widget;
+ GdkWindow *window;
+ GdkRectangle rect;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ view = GTK_TEXT_VIEW (widget);
+
+ window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
+ gdk_window_get_origin (window, &x_widget, &y_widget);
+
+ if (coords == ATK_XY_SCREEN)
+ {
+ x = x - x_widget;
+ y = y - y_widget;
+ }
+ else if (coords == ATK_XY_WINDOW)
+ {
+ window = gdk_window_get_toplevel (window);
+ gdk_window_get_origin (window, &x_window, &y_window);
+
+ x = x - x_widget + x_window;
+ y = y - y_widget + y_window;
+ }
+ else
+ return -1;
+
+ gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_WIDGET,
+ x, y, &buff_x, &buff_y);
+ gtk_text_view_get_visible_rect (view, &rect);
+ /*
+ * Clamp point to visible rectangle
+ */
+ buff_x = CLAMP (buff_x, rect.x, rect.x + rect.width - 1);
+ buff_y = CLAMP (buff_y, rect.y, rect.y + rect.height - 1);
+
+ gtk_text_view_get_iter_at_location (view, &loc_itr, buff_x, buff_y);
+ /*
+ * The iter at a location sometimes points to the next character.
+ * See bug 111031. We work around that
+ */
+ gtk_text_view_get_iter_location (view, &loc_itr, &rect);
+ if (buff_x < rect.x)
+ gtk_text_iter_backward_char (&loc_itr);
+ return gtk_text_iter_get_offset (&loc_itr);
+}
+
+static void
+gail_text_view_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GtkTextView *view;
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+ GtkWidget *widget;
+ GdkRectangle rectangle;
+ GdkWindow *window;
+ gint x_widget, y_widget, x_window, y_window;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
+ gtk_text_view_get_iter_location (view, &iter, &rectangle);
+
+ window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
+ gdk_window_get_origin (window, &x_widget, &y_widget);
+
+ *height = rectangle.height;
+ *width = rectangle.width;
+
+ gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_WIDGET,
+ rectangle.x, rectangle.y, x, y);
+ if (coords == ATK_XY_WINDOW)
+ {
+ window = gdk_window_get_toplevel (window);
+ gdk_window_get_origin (window, &x_window, &y_window);
+ *x += x_widget - x_window;
+ *y += y_widget - y_window;
+ }
+ else if (coords == ATK_XY_SCREEN)
+ {
+ *x += x_widget;
+ *y += y_widget;
+ }
+ else
+ {
+ *x = 0;
+ *y = 0;
+ *height = 0;
+ *width = 0;
+ }
+}
+
+static AtkAttributeSet*
+gail_text_view_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkTextView *view;
+ GtkTextBuffer *buffer;
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+
+ return gail_misc_buffer_get_run_attributes (buffer, offset,
+ start_offset, end_offset);
+}
+
+static AtkAttributeSet*
+add_text_attribute (AtkAttributeSet *attrib_set, AtkTextAttribute attr, gint i)
+{
+ const gchar *value;
+
+ value = atk_text_attribute_get_value (attr, i);
+
+ return gail_misc_add_attribute (attrib_set, i, g_strdup (value));
+}
+
+static AtkAttributeSet*
+gail_text_view_get_default_attributes (AtkText *text)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextAttributes *text_attrs;
+ AtkAttributeSet *attrib_set = NULL;
+ PangoFontDescription *font;
+ gchar *value;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ view = GTK_TEXT_VIEW (widget);
+ text_attrs = gtk_text_view_get_default_attributes (view);
+
+ font = text_attrs->font;
+
+ if (font)
+ {
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_STYLE,
+ pango_font_description_get_style (font));
+
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT,
+ pango_font_description_get_variant (font));
+
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH,
+ pango_font_description_get_stretch (font));
+
+ value = g_strdup (pango_font_description_get_family (font));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
+
+ value = g_strdup_printf ("%d", pango_font_description_get_weight (font));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
+
+ value = g_strdup_printf ("%i", pango_font_description_get_size (font) / PANGO_SCALE);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
+ }
+
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, text_attrs->justification);
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, text_attrs->direction);
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, text_attrs->wrap_mode);
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, text_attrs->editable);
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, text_attrs->invisible);
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, text_attrs->bg_full_height);
+
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH,
+ text_attrs->appearance.strikethrough);
+ attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE,
+ text_attrs->appearance.underline);
+
+ value = g_strdup_printf ("%u,%u,%u",
+ text_attrs->appearance.bg_color.red,
+ text_attrs->appearance.bg_color.green,
+ text_attrs->appearance.bg_color.blue);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
+
+ value = g_strdup_printf ("%u,%u,%u",
+ text_attrs->appearance.fg_color.red,
+ text_attrs->appearance.fg_color.green,
+ text_attrs->appearance.fg_color.blue);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
+
+ value = g_strdup_printf ("%g", text_attrs->font_scale);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_SCALE, value);
+
+ value = g_strdup ((gchar *)(text_attrs->language));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
+
+ value = g_strdup_printf ("%i", text_attrs->appearance.rise);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
+
+ value = g_strdup_printf ("%i", text_attrs->pixels_inside_wrap);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
+
+ value = g_strdup_printf ("%i", text_attrs->pixels_below_lines);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
+
+ value = g_strdup_printf ("%i", text_attrs->pixels_above_lines);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
+
+ value = g_strdup_printf ("%i", text_attrs->indent);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
+
+ value = g_strdup_printf ("%i", text_attrs->left_margin);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
+
+ value = g_strdup_printf ("%i", text_attrs->right_margin);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
+
+ gtk_text_attributes_unref (text_attrs);
+ return attrib_set;
+}
+
+static gint
+gail_text_view_get_n_selections (AtkText *text)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ gint select_start, select_end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+ select_start = gtk_text_iter_get_offset (&start);
+ select_end = gtk_text_iter_get_offset (&end);
+
+ if (select_start != select_end)
+ return 1;
+ else
+ return 0;
+}
+
+static gchar*
+gail_text_view_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_pos,
+ gint *end_pos)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ /* Only let the user get the selection if one is set, and if the
+ * selection_num is 0.
+ */
+ if (selection_num != 0)
+ return NULL;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+ *start_pos = gtk_text_iter_get_offset (&start);
+ *end_pos = gtk_text_iter_get_offset (&end);
+
+ if (*start_pos != *end_pos)
+ return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+ else
+ return NULL;
+}
+
+static gboolean
+gail_text_view_add_selection (AtkText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter pos_itr;
+ GtkTextIter start, end;
+ gint select_start, select_end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+ select_start = gtk_text_iter_get_offset (&start);
+ select_end = gtk_text_iter_get_offset (&end);
+
+ /* If there is already a selection, then don't allow another to be added,
+ * since GtkTextView only supports one selected region.
+ */
+ if (select_start == select_end)
+ {
+ gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, start_pos);
+ gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", &pos_itr);
+ gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, end_pos);
+ gtk_text_buffer_move_mark_by_name (buffer, "insert", &pos_itr);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+gail_text_view_remove_selection (AtkText *text,
+ gint selection_num)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextMark *cursor_mark;
+ GtkTextIter cursor_itr;
+ GtkTextIter start, end;
+ gint select_start, select_end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ if (selection_num != 0)
+ return FALSE;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_selection_bounds(buffer, &start, &end);
+ select_start = gtk_text_iter_get_offset(&start);
+ select_end = gtk_text_iter_get_offset(&end);
+
+ if (select_start != select_end)
+ {
+ /* Setting the start & end of the selected region to the caret position
+ * turns off the selection.
+ */
+ cursor_mark = gtk_text_buffer_get_insert (buffer);
+ gtk_text_buffer_get_iter_at_mark (buffer, &cursor_itr, cursor_mark);
+ gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", &cursor_itr);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+gail_text_view_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter pos_itr;
+ GtkTextIter start, end;
+ gint select_start, select_end;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ {
+ /* State is defunct */
+ return FALSE;
+ }
+
+ /* Only let the user move the selection if one is set, and if the
+ * selection_num is 0
+ */
+ if (selection_num != 0)
+ return FALSE;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_selection_bounds(buffer, &start, &end);
+ select_start = gtk_text_iter_get_offset(&start);
+ select_end = gtk_text_iter_get_offset(&end);
+
+ if (select_start != select_end)
+ {
+ gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, start_pos);
+ gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", &pos_itr);
+ gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, end_pos);
+ gtk_text_buffer_move_mark_by_name (buffer, "insert", &pos_itr);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/* atkeditabletext.h */
+
+static void
+atk_editable_text_interface_init (AtkEditableTextIface *iface)
+{
+ iface->set_text_contents = gail_text_view_set_text_contents;
+ iface->insert_text = gail_text_view_insert_text;
+ iface->copy_text = gail_text_view_copy_text;
+ iface->cut_text = gail_text_view_cut_text;
+ iface->delete_text = gail_text_view_delete_text;
+ iface->paste_text = gail_text_view_paste_text;
+ iface->set_run_attributes = gail_text_view_set_run_attributes;
+}
+
+static gboolean
+gail_text_view_set_run_attributes (AtkEditableText *text,
+ AtkAttributeSet *attrib_set,
+ gint start_offset,
+ gint end_offset)
+{
+ GtkTextView *view;
+ GtkTextBuffer *buffer;
+ GtkWidget *widget;
+ GtkTextTag *tag;
+ GtkTextIter start;
+ GtkTextIter end;
+ gint j;
+ GdkColor *color;
+ gchar** RGB_vals;
+ GSList *l;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ view = GTK_TEXT_VIEW (widget);
+ if (!gtk_text_view_get_editable (view))
+ return FALSE;
+
+ buffer = gtk_text_view_get_buffer (view);
+
+ if (attrib_set == NULL)
+ return FALSE;
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
+
+ tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
+
+ for (l = attrib_set; l; l = l->next)
+ {
+ gchar *name;
+ gchar *value;
+ AtkAttribute *at;
+
+ at = l->data;
+
+ name = at->name;
+ value = at->value;
+
+ if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LEFT_MARGIN)))
+ g_object_set (G_OBJECT (tag), "left_margin", atoi (value), NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RIGHT_MARGIN)))
+ g_object_set (G_OBJECT (tag), "right_margin", atoi (value), NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INDENT)))
+ g_object_set (G_OBJECT (tag), "indent", atoi (value), NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_ABOVE_LINES)))
+ g_object_set (G_OBJECT (tag), "pixels_above_lines", atoi (value), NULL);
+
+ else if (!strcmp(name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_BELOW_LINES)))
+ g_object_set (G_OBJECT (tag), "pixels_below_lines", atoi (value), NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP)))
+ g_object_set (G_OBJECT (tag), "pixels_inside_wrap", atoi (value), NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_SIZE)))
+ g_object_set (G_OBJECT (tag), "size", atoi (value), NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RISE)))
+ g_object_set (G_OBJECT (tag), "rise", atoi (value), NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WEIGHT)))
+ g_object_set (G_OBJECT (tag), "weight", atoi (value), NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_FULL_HEIGHT)))
+ {
+ g_object_set (G_OBJECT (tag), "bg_full_height",
+ (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, 0))),
+ NULL);
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LANGUAGE)))
+ g_object_set (G_OBJECT (tag), "language", value, NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FAMILY_NAME)))
+ g_object_set (G_OBJECT (tag), "family", value, NULL);
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_EDITABLE)))
+ {
+ g_object_set (G_OBJECT (tag), "editable",
+ (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
+ NULL);
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INVISIBLE)))
+ {
+ g_object_set (G_OBJECT (tag), "invisible",
+ (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
+ NULL);
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_UNDERLINE)))
+ {
+ for (j = 0; j < 3; j++)
+ {
+ if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, j)))
+ {
+ g_object_set (G_OBJECT (tag), "underline", j, NULL);
+ break;
+ }
+ }
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRIKETHROUGH)))
+ {
+ g_object_set (G_OBJECT (tag), "strikethrough",
+ (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, 0))),
+ NULL);
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_COLOR)))
+ {
+ RGB_vals = g_strsplit (value, ",", 3);
+ color = g_malloc (sizeof (GdkColor));
+ color->red = atoi (RGB_vals[0]);
+ color->green = atoi (RGB_vals[1]);
+ color->blue = atoi (RGB_vals[2]);
+ g_object_set (G_OBJECT (tag), "background_gdk", color, NULL);
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FG_COLOR)))
+ {
+ RGB_vals = g_strsplit (value, ",", 3);
+ color = g_malloc (sizeof (GdkColor));
+ color->red = atoi (RGB_vals[0]);
+ color->green = atoi (RGB_vals[1]);
+ color->blue = atoi (RGB_vals[2]);
+ g_object_set (G_OBJECT (tag), "foreground_gdk", color, NULL);
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRETCH)))
+ {
+ for (j = 0; j < 9; j++)
+ {
+ if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, j)))
+ {
+ g_object_set (G_OBJECT (tag), "stretch", j, NULL);
+ break;
+ }
+ }
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_JUSTIFICATION)))
+ {
+ for (j = 0; j < 4; j++)
+ {
+ if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, j)))
+ {
+ g_object_set (G_OBJECT (tag), "justification", j, NULL);
+ break;
+ }
+ }
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_DIRECTION)))
+ {
+ for (j = 0; j < 3; j++)
+ {
+ if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, j)))
+ {
+ g_object_set (G_OBJECT (tag), "direction", j, NULL);
+ break;
+ }
+ }
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_VARIANT)))
+ {
+ for (j = 0; j < 2; j++)
+ {
+ if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, j)))
+ {
+ g_object_set (G_OBJECT (tag), "variant", j, NULL);
+ break;
+ }
+ }
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WRAP_MODE)))
+ {
+ for (j = 0; j < 3; j++)
+ {
+ if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, j)))
+ {
+ g_object_set (G_OBJECT (tag), "wrap_mode", j, NULL);
+ break;
+ }
+ }
+ }
+
+ else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STYLE)))
+ {
+ for (j = 0; j < 3; j++)
+ {
+ if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, j)))
+ {
+ g_object_set (G_OBJECT (tag), "style", j, NULL);
+ break;
+ }
+ }
+ }
+
+ else
+ return FALSE;
+ }
+
+ gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
+
+ return TRUE;
+}
+
+static void
+gail_text_view_set_text_contents (AtkEditableText *text,
+ const gchar *string)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ view = GTK_TEXT_VIEW (widget);
+ if (!gtk_text_view_get_editable (view))
+ return;
+ buffer = gtk_text_view_get_buffer (view);
+
+ /* The -1 indicates that the input string must be null-terminated */
+ gtk_text_buffer_set_text (buffer, string, -1);
+}
+
+static void
+gail_text_view_insert_text (AtkEditableText *text,
+ const gchar *string,
+ gint length,
+ gint *position)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter pos_itr;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ view = GTK_TEXT_VIEW (widget);
+ if (!gtk_text_view_get_editable (view))
+ return;
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, *position);
+ gtk_text_buffer_insert (buffer, &pos_itr, string, length);
+}
+
+static void
+gail_text_view_copy_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ gchar *str;
+ GtkClipboard *clipboard;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ view = GTK_TEXT_VIEW (widget);
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
+ str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
+ GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, str, -1);
+}
+
+static void
+gail_text_view_cut_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+ gchar *str;
+ GtkClipboard *clipboard;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ view = GTK_TEXT_VIEW (widget);
+ if (!gtk_text_view_get_editable (view))
+ return;
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
+ str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
+ GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, str, -1);
+ gtk_text_buffer_delete (buffer, &start, &end);
+}
+
+static void
+gail_text_view_delete_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GtkTextIter start_itr;
+ GtkTextIter end_itr;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ view = GTK_TEXT_VIEW (widget);
+ if (!gtk_text_view_get_editable (view))
+ return;
+ buffer = gtk_text_view_get_buffer (view);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &start_itr, start_pos);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end_itr, end_pos);
+ gtk_text_buffer_delete (buffer, &start_itr, &end_itr);
+}
+
+static void
+gail_text_view_paste_text (AtkEditableText *text,
+ gint position)
+{
+ GtkTextView *view;
+ GtkWidget *widget;
+ GtkTextBuffer *buffer;
+ GailTextViewPaste paste_struct;
+ GtkClipboard *clipboard;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ view = GTK_TEXT_VIEW (widget);
+ if (!gtk_text_view_get_editable (view))
+ return;
+ buffer = gtk_text_view_get_buffer (view);
+
+ paste_struct.buffer = buffer;
+ paste_struct.position = position;
+
+ g_object_ref (paste_struct.buffer);
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
+ GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_request_text (clipboard,
+ gail_text_view_paste_received, &paste_struct);
+}
+
+static void
+gail_text_view_paste_received (GtkClipboard *clipboard,
+ const gchar *text,
+ gpointer data)
+{
+ GailTextViewPaste* paste_struct = (GailTextViewPaste *)data;
+ GtkTextIter pos_itr;
+
+ if (text)
+ {
+ gtk_text_buffer_get_iter_at_offset (paste_struct->buffer, &pos_itr,
+ paste_struct->position);
+ gtk_text_buffer_insert (paste_struct->buffer, &pos_itr, text, -1);
+ }
+
+ g_object_unref (paste_struct->buffer);
+}
+
+/* Callbacks */
+
+/* Note arg1 returns the start of the insert range, arg3 returns the
+ * end of the insert range if multiple characters are inserted. If one
+ * character is inserted they have the same value, which is the caret
+ * location. arg2 returns the begin location of the insert.
+ */
+static void
+_gail_text_view_insert_text_cb (GtkTextBuffer *buffer,
+ GtkTextIter *arg1,
+ gchar *arg2,
+ gint arg3,
+ gpointer user_data)
+{
+ GtkTextView *text = (GtkTextView *) user_data;
+ AtkObject *accessible;
+ GailTextView *gail_text_view;
+ gint position;
+ gint length;
+
+ g_return_if_fail (arg3 > 0);
+
+ accessible = gtk_widget_get_accessible(GTK_WIDGET(text));
+ gail_text_view = GAIL_TEXT_VIEW (accessible);
+
+ gail_text_view->signal_name = "text_changed::insert";
+ position = gtk_text_iter_get_offset (arg1);
+ length = g_utf8_strlen(arg2, arg3);
+
+ if (gail_text_view->length == 0)
+ {
+ gail_text_view->position = position;
+ gail_text_view->length = length;
+ }
+ else if (gail_text_view->position + gail_text_view->length == position)
+ {
+ gail_text_view->length += length;
+ }
+ else
+ {
+ /*
+ * We have a non-contiguous insert so report what we have
+ */
+ if (gail_text_view->insert_notify_handler)
+ {
+ g_source_remove (gail_text_view->insert_notify_handler);
+ }
+ gail_text_view->insert_notify_handler = 0;
+ insert_idle_handler (gail_text_view);
+ gail_text_view->position = position;
+ gail_text_view->length = length;
+ }
+
+ /*
+ * The signal will be emitted when the changed signal is received
+ */
+}
+
+/* Note arg1 returns the start of the delete range, arg2 returns the
+ * end of the delete range if multiple characters are deleted. If one
+ * character is deleted they have the same value, which is the caret
+ * location.
+ */
+static void
+_gail_text_view_delete_range_cb (GtkTextBuffer *buffer,
+ GtkTextIter *arg1,
+ GtkTextIter *arg2,
+ gpointer user_data)
+{
+ GtkTextView *text = (GtkTextView *) user_data;
+ AtkObject *accessible;
+ GailTextView *gail_text_view;
+ gint offset = gtk_text_iter_get_offset (arg1);
+ gint length = gtk_text_iter_get_offset (arg2) - offset;
+
+ accessible = gtk_widget_get_accessible(GTK_WIDGET(text));
+ gail_text_view = GAIL_TEXT_VIEW (accessible);
+ if (gail_text_view->insert_notify_handler)
+ {
+ g_source_remove (gail_text_view->insert_notify_handler);
+ gail_text_view->insert_notify_handler = 0;
+ if (gail_text_view->position == offset &&
+ gail_text_view->length == length)
+ {
+ /*
+ * Do not bother with insert and delete notifications
+ */
+ gail_text_view->signal_name = NULL;
+ gail_text_view->position = 0;
+ gail_text_view->length = 0;
+ return;
+ }
+
+ insert_idle_handler (gail_text_view);
+ }
+ g_signal_emit_by_name (accessible, "text_changed::delete",
+ offset, length);
+}
+
+/* Note arg1 and arg2 point to the same offset, which is the caret
+ * position after the move
+ */
+static void
+_gail_text_view_mark_set_cb (GtkTextBuffer *buffer,
+ GtkTextIter *arg1,
+ GtkTextMark *arg2,
+ gpointer user_data)
+{
+ GtkTextView *text = (GtkTextView *) user_data;
+ AtkObject *accessible;
+ GailTextView *gail_text_view;
+ const char *mark_name = gtk_text_mark_get_name(arg2);
+
+ accessible = gtk_widget_get_accessible(GTK_WIDGET(text));
+ gail_text_view = GAIL_TEXT_VIEW (accessible);
+
+ /*
+ * Only generate the signal for the "insert" mark, which
+ * represents the cursor.
+ */
+ if (mark_name && !strcmp(mark_name, "insert"))
+ {
+ int insert_offset, selection_bound;
+ gboolean selection_changed;
+
+ insert_offset = gtk_text_iter_get_offset (arg1);
+
+ selection_bound = get_selection_bound (buffer);
+ if (selection_bound != insert_offset)
+ {
+ if (selection_bound != gail_text_view->previous_selection_bound ||
+ insert_offset != gail_text_view->previous_insert_offset)
+ {
+ selection_changed = TRUE;
+ }
+ else
+ {
+ selection_changed = FALSE;
+ }
+ }
+ else if (gail_text_view->previous_selection_bound != gail_text_view->previous_insert_offset)
+ {
+ selection_changed = TRUE;
+ }
+ else
+ {
+ selection_changed = FALSE;
+ }
+
+ emit_text_caret_moved (gail_text_view, insert_offset);
+ /*
+ * insert and selection_bound marks are different to a selection
+ * has changed
+ */
+ if (selection_changed)
+ g_signal_emit_by_name (accessible, "text_selection_changed");
+ gail_text_view->previous_selection_bound = selection_bound;
+ }
+}
+
+static void
+_gail_text_view_changed_cb (GtkTextBuffer *buffer,
+ gpointer user_data)
+{
+ GtkTextView *text = (GtkTextView *) user_data;
+ AtkObject *accessible;
+ GailTextView *gail_text_view;
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (text));
+ gail_text_view = GAIL_TEXT_VIEW (accessible);
+ if (gail_text_view->signal_name)
+ {
+ if (!gail_text_view->insert_notify_handler)
+ {
+ gail_text_view->insert_notify_handler = gdk_threads_add_idle (insert_idle_handler, accessible);
+ }
+ return;
+ }
+ emit_text_caret_moved (gail_text_view, get_insert_offset (buffer));
+ gail_text_view->previous_selection_bound = get_selection_bound (buffer);
+}
+
+static gchar*
+get_text_near_offset (AtkText *text,
+ GailOffsetType function,
+ AtkTextBoundary boundary_type,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkTextView *view;
+ gpointer layout = NULL;
+
+ view = GTK_TEXT_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (text)));
+
+ /*
+ * Pass the GtkTextView to the function gail_text_util_get_text()
+ * so it can find the start and end of the current line on the display.
+ */
+ if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START ||
+ boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
+ layout = view;
+
+ return gail_text_util_get_text (GAIL_TEXT_VIEW (text)->textutil, layout,
+ function, boundary_type, offset,
+ start_offset, end_offset);
+}
+
+static gint
+get_insert_offset (GtkTextBuffer *buffer)
+{
+ GtkTextMark *cursor_mark;
+ GtkTextIter cursor_itr;
+
+ cursor_mark = gtk_text_buffer_get_insert (buffer);
+ gtk_text_buffer_get_iter_at_mark (buffer, &cursor_itr, cursor_mark);
+ return gtk_text_iter_get_offset (&cursor_itr);
+}
+
+static gint
+get_selection_bound (GtkTextBuffer *buffer)
+{
+ GtkTextMark *selection_mark;
+ GtkTextIter selection_itr;
+
+ selection_mark = gtk_text_buffer_get_selection_bound (buffer);
+ gtk_text_buffer_get_iter_at_mark (buffer, &selection_itr, selection_mark);
+ return gtk_text_iter_get_offset (&selection_itr);
+}
+
+static void
+emit_text_caret_moved (GailTextView *gail_text_view,
+ gint insert_offset)
+{
+ /*
+ * If we have text which has been inserted notify the user
+ */
+ if (gail_text_view->insert_notify_handler)
+ {
+ g_source_remove (gail_text_view->insert_notify_handler);
+ gail_text_view->insert_notify_handler = 0;
+ insert_idle_handler (gail_text_view);
+ }
+
+ if (insert_offset != gail_text_view->previous_insert_offset)
+ {
+ /*
+ * If the caret position has not changed then don't bother notifying
+ *
+ * When mouse click is used to change caret position, notification
+ * is received on button down and button up.
+ */
+ g_signal_emit_by_name (gail_text_view, "text_caret_moved", insert_offset);
+ gail_text_view->previous_insert_offset = insert_offset;
+ }
+}
+
+static gint
+insert_idle_handler (gpointer data)
+{
+ GailTextView *gail_text_view;
+ GtkTextBuffer *buffer;
+
+ gail_text_view = GAIL_TEXT_VIEW (data);
+
+ g_signal_emit_by_name (data,
+ gail_text_view->signal_name,
+ gail_text_view->position,
+ gail_text_view->length);
+ gail_text_view->signal_name = NULL;
+ gail_text_view->position = 0;
+ gail_text_view->length = 0;
+
+ buffer = gail_text_view->textutil->buffer;
+ if (gail_text_view->insert_notify_handler)
+ {
+ /*
+ * If called from idle handler notify caret moved
+ */
+ gail_text_view->insert_notify_handler = 0;
+ emit_text_caret_moved (gail_text_view, get_insert_offset (buffer));
+ gail_text_view->previous_selection_bound = get_selection_bound (buffer);
+ }
+
+ return FALSE;
+}
+
+static void
+atk_streamable_content_interface_init (AtkStreamableContentIface *iface)
+{
+ iface->get_n_mime_types = gail_streamable_content_get_n_mime_types;
+ iface->get_mime_type = gail_streamable_content_get_mime_type;
+ iface->get_stream = gail_streamable_content_get_stream;
+}
+
+static gint gail_streamable_content_get_n_mime_types (AtkStreamableContent *streamable)
+{
+ gint n_mime_types = 0;
+
+ if (GAIL_IS_TEXT_VIEW (streamable) && GAIL_TEXT_VIEW (streamable)->textutil)
+ {
+ int i;
+ gboolean advertises_plaintext = FALSE;
+ GdkAtom *atoms =
+ gtk_text_buffer_get_serialize_formats (
+ GAIL_TEXT_VIEW (streamable)->textutil->buffer,
+ &n_mime_types);
+ for (i = 0; i < n_mime_types-1; ++i)
+ if (!strcmp ("text/plain", gdk_atom_name (atoms[i])))
+ advertises_plaintext = TRUE;
+ if (!advertises_plaintext) ++n_mime_types;
+ /* we support text/plain even if the GtkTextBuffer doesn't */
+ }
+ return n_mime_types;
+}
+
+static const gchar*
+gail_streamable_content_get_mime_type (AtkStreamableContent *streamable, gint i)
+{
+ if (GAIL_IS_TEXT_VIEW (streamable) && GAIL_TEXT_VIEW (streamable)->textutil)
+ {
+ gint n_mime_types = 0;
+ GdkAtom *atoms;
+ atoms = gtk_text_buffer_get_serialize_formats (
+ GAIL_TEXT_VIEW (streamable)->textutil->buffer,
+ &n_mime_types);
+ if (i < n_mime_types)
+ {
+ return gdk_atom_name (atoms [i]);
+ }
+ else if (i == n_mime_types)
+ return "text/plain";
+ }
+ return NULL;
+}
+
+static GIOChannel* gail_streamable_content_get_stream (AtkStreamableContent *streamable,
+ const gchar *mime_type)
+{
+ gint i, n_mime_types = 0;
+ GdkAtom *atoms;
+ if (!GAIL_IS_TEXT_VIEW (streamable) || !GAIL_TEXT_VIEW (streamable)->textutil)
+ return NULL;
+ atoms = gtk_text_buffer_get_serialize_formats (
+ GAIL_TEXT_VIEW (streamable)->textutil->buffer,
+ &n_mime_types);
+ for (i = 0; i < n_mime_types; ++i)
+ {
+ if (!strcmp ("text/plain", mime_type) ||
+ !strcmp (gdk_atom_name (atoms[i]), mime_type)) {
+ GtkTextBuffer *buffer;
+ guint8 *cbuf;
+ GError *err = NULL;
+ gsize len, written;
+ gchar tname[80];
+ GtkTextIter start, end;
+ GIOChannel *gio = NULL;
+ int fd;
+ buffer = GAIL_TEXT_VIEW (streamable)->textutil->buffer;
+ gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end, -1);
+ if (!strcmp ("text/plain", mime_type))
+ {
+ cbuf = (guint8*) gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+ len = strlen ((const char *) cbuf);
+ }
+ else
+ {
+ cbuf = gtk_text_buffer_serialize (buffer, buffer, atoms[i], &start, &end, &len);
+ }
+ g_snprintf (tname, 20, "streamXXXXXX");
+ fd = g_mkstemp (tname);
+ gio = g_io_channel_unix_new (fd);
+ g_io_channel_set_encoding (gio, NULL, &err);
+ if (!err) g_io_channel_write_chars (gio, (const char *) cbuf, (gssize) len, &written, &err);
+ else g_message ("%s", err->message);
+ if (!err) g_io_channel_seek_position (gio, 0, G_SEEK_SET, &err);
+ else g_message ("%s", err->message);
+ if (!err) g_io_channel_flush (gio, &err);
+ else g_message ("%s", err->message);
+ if (err) {
+ g_message ("<error writing to stream [%s]>", tname);
+ g_error_free (err);
+ }
+ /* make sure the file is removed on unref of the giochannel */
+ else {
+ g_unlink (tname);
+ return gio;
+ }
+ }
+ }
+ return NULL;
+}
+
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_TEXT_VIEW_H__
+#define __GAIL_TEXT_VIEW_H__
+
+#include "gailcontainer.h"
+#include <libgail-util/gailtextutil.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_TEXT_VIEW (gail_text_view_get_type ())
+#define GAIL_TEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TEXT_VIEW, GailTextView))
+#define GAIL_TEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TEXT_VIEW, GailTextViewClass))
+#define GAIL_IS_TEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TEXT_VIEW))
+#define GAIL_IS_TEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TEXT_VIEW))
+#define GAIL_TEXT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TEXT_VIEW, GailTextViewClass))
+
+typedef struct _GailTextView GailTextView;
+typedef struct _GailTextViewClass GailTextViewClass;
+
+struct _GailTextView
+{
+ GailContainer parent;
+
+ GailTextUtil *textutil;
+ gint previous_insert_offset;
+ gint previous_selection_bound;
+ /*
+ * These fields store information about text changed
+ */
+ gchar *signal_name;
+ gint position;
+ gint length;
+
+ guint insert_notify_handler;
+};
+
+GType gail_text_view_get_type (void);
+
+struct _GailTextViewClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_TEXT_VIEW_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailtogglebutton.h"
+
+static void gail_toggle_button_class_init (GailToggleButtonClass *klass);
+
+static void gail_toggle_button_init (GailToggleButton *button);
+
+static void gail_toggle_button_toggled_gtk (GtkWidget *widget);
+
+static void gail_toggle_button_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+
+static void gail_toggle_button_real_initialize (AtkObject *obj,
+ gpointer data);
+
+static AtkStateSet* gail_toggle_button_ref_state_set (AtkObject *accessible);
+
+G_DEFINE_TYPE (GailToggleButton, gail_toggle_button, GAIL_TYPE_BUTTON)
+
+static void
+gail_toggle_button_class_init (GailToggleButtonClass *klass)
+{
+ GailWidgetClass *widget_class;
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ widget_class = (GailWidgetClass*)klass;
+ widget_class->notify_gtk = gail_toggle_button_real_notify_gtk;
+
+ class->ref_state_set = gail_toggle_button_ref_state_set;
+ class->initialize = gail_toggle_button_real_initialize;
+}
+
+static void
+gail_toggle_button_init (GailToggleButton *button)
+{
+}
+
+static void
+gail_toggle_button_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_toggle_button_parent_class)->initialize (obj, data);
+
+ g_signal_connect (data,
+ "toggled",
+ G_CALLBACK (gail_toggle_button_toggled_gtk),
+ NULL);
+
+ if (GTK_IS_CHECK_BUTTON (data))
+ obj->role = ATK_ROLE_CHECK_BOX;
+ else
+ obj->role = ATK_ROLE_TOGGLE_BUTTON;
+}
+
+static void
+gail_toggle_button_toggled_gtk (GtkWidget *widget)
+{
+ AtkObject *accessible;
+ GtkToggleButton *toggle_button;
+
+ toggle_button = GTK_TOGGLE_BUTTON (widget);
+
+ accessible = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (accessible, ATK_STATE_CHECKED,
+ gtk_toggle_button_get_active (toggle_button));
+}
+
+static AtkStateSet*
+gail_toggle_button_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GtkToggleButton *toggle_button;
+ GtkWidget *widget;
+
+ state_set = ATK_OBJECT_CLASS (gail_toggle_button_parent_class)->ref_state_set (accessible);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ return state_set;
+
+ toggle_button = GTK_TOGGLE_BUTTON (widget);
+
+ if (gtk_toggle_button_get_active (toggle_button))
+ atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
+
+ if (gtk_toggle_button_get_inconsistent (toggle_button))
+ {
+ atk_state_set_remove_state (state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (state_set, ATK_STATE_INDETERMINATE);
+ }
+
+ return state_set;
+}
+
+static void
+gail_toggle_button_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (obj);
+ AtkObject *atk_obj;
+ gboolean sensitive;
+ gboolean inconsistent;
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (toggle_button));
+ sensitive = gtk_widget_get_sensitive (GTK_WIDGET (toggle_button));
+ inconsistent = gtk_toggle_button_get_inconsistent (toggle_button);
+
+ if (strcmp (pspec->name, "inconsistent") == 0)
+ {
+ atk_object_notify_state_change (atk_obj, ATK_STATE_INDETERMINATE, inconsistent);
+ atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
+ }
+ else if (strcmp (pspec->name, "sensitive") == 0)
+ {
+ /* Need to override gailwidget behavior of notifying for ENABLED */
+ atk_object_notify_state_change (atk_obj, ATK_STATE_SENSITIVE, sensitive);
+ atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_toggle_button_parent_class)->notify_gtk (obj, pspec);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_TOGGLE_BUTTON_H__
+#define __GAIL_TOGGLE_BUTTON_H__
+
+#include "gailbutton.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_TOGGLE_BUTTON (gail_toggle_button_get_type ())
+#define GAIL_TOGGLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TOGGLE_BUTTON, GailToggleButton))
+#define GAIL_TOGGLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TOGGLE_BUTTON, GailToggleButtonClass))
+#define GAIL_IS_TOGGLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TOGGLE_BUTTON))
+#define GAIL_IS_TOGGLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TOGGLE_BUTTON))
+#define GAIL_TOGGLE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TOGGLE_BUTTON, GailToggleButtonClass))
+
+typedef struct _GailToggleButton GailToggleButton;
+typedef struct _GailToggleButtonClass GailToggleButtonClass;
+
+struct _GailToggleButton
+{
+ GailButton parent;
+};
+
+GType gail_toggle_button_get_type (void);
+
+struct _GailToggleButtonClass
+{
+ GailButtonClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_TOGGLE_BUTTON_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtkx.h>
+
+#include "gailtoplevel.h"
+
+static void gail_toplevel_class_init (GailToplevelClass *klass);
+static void gail_toplevel_init (GailToplevel *toplevel);
+static void gail_toplevel_initialize (AtkObject *accessible,
+ gpointer data);
+static void gail_toplevel_object_finalize (GObject *obj);
+
+/* atkobject.h */
+
+static gint gail_toplevel_get_n_children (AtkObject *obj);
+static AtkObject* gail_toplevel_ref_child (AtkObject *obj,
+ gint i);
+static AtkObject* gail_toplevel_get_parent (AtkObject *obj);
+
+/* Callbacks */
+
+
+static void gail_toplevel_window_destroyed (GtkWindow *window,
+ GailToplevel *text);
+static gboolean gail_toplevel_hide_event_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static gboolean gail_toplevel_show_event_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+
+/* Misc */
+
+static void _gail_toplevel_remove_child (GailToplevel *toplevel,
+ GtkWindow *window);
+static gboolean is_attached_menu_window (GtkWidget *widget);
+static gboolean is_combo_window (GtkWidget *widget);
+
+
+G_DEFINE_TYPE (GailToplevel, gail_toplevel, ATK_TYPE_OBJECT)
+
+static void
+gail_toplevel_class_init (GailToplevelClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS(klass);
+ GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
+
+ class->initialize = gail_toplevel_initialize;
+ class->get_n_children = gail_toplevel_get_n_children;
+ class->ref_child = gail_toplevel_ref_child;
+ class->get_parent = gail_toplevel_get_parent;
+
+ g_object_class->finalize = gail_toplevel_object_finalize;
+}
+
+static void
+gail_toplevel_init (GailToplevel *toplevel)
+{
+ GtkWindow *window;
+ GtkWidget *widget;
+ GList *l;
+ guint signal_id;
+
+ l = toplevel->window_list = gtk_window_list_toplevels ();
+
+ while (l)
+ {
+ window = GTK_WINDOW (l->data);
+ widget = GTK_WIDGET (window);
+ if (!window ||
+ !gtk_widget_get_visible (widget) ||
+ is_attached_menu_window (widget) ||
+#ifdef GDK_WINDOWING_X11
+ GTK_IS_PLUG (window) ||
+#endif
+ gtk_widget_get_parent (GTK_WIDGET (window)))
+ {
+ GList *temp_l = l->next;
+
+ toplevel->window_list = g_list_delete_link (toplevel->window_list, l);
+ l = temp_l;
+ }
+ else
+ {
+ g_signal_connect (G_OBJECT (window),
+ "destroy",
+ G_CALLBACK (gail_toplevel_window_destroyed),
+ toplevel);
+ l = l->next;
+ }
+ }
+
+ g_type_class_ref (GTK_TYPE_WINDOW);
+
+ signal_id = g_signal_lookup ("show", GTK_TYPE_WINDOW);
+ g_signal_add_emission_hook (signal_id, 0,
+ gail_toplevel_show_event_watcher, toplevel, (GDestroyNotify) NULL);
+
+ signal_id = g_signal_lookup ("hide", GTK_TYPE_WINDOW);
+ g_signal_add_emission_hook (signal_id, 0,
+ gail_toplevel_hide_event_watcher, toplevel, (GDestroyNotify) NULL);
+}
+
+static void
+gail_toplevel_initialize (AtkObject *accessible,
+ gpointer data)
+{
+ ATK_OBJECT_CLASS (gail_toplevel_parent_class)->initialize (accessible, data);
+
+ accessible->role = ATK_ROLE_APPLICATION;
+ accessible->name = g_get_prgname();
+ accessible->accessible_parent = NULL;
+}
+
+static void
+gail_toplevel_object_finalize (GObject *obj)
+{
+ GailToplevel *toplevel = GAIL_TOPLEVEL (obj);
+
+ if (toplevel->window_list)
+ g_list_free (toplevel->window_list);
+
+ G_OBJECT_CLASS (gail_toplevel_parent_class)->finalize (obj);
+}
+
+static AtkObject*
+gail_toplevel_get_parent (AtkObject *obj)
+{
+ return NULL;
+}
+
+static gint
+gail_toplevel_get_n_children (AtkObject *obj)
+{
+ GailToplevel *toplevel = GAIL_TOPLEVEL (obj);
+
+ gint rc = g_list_length (toplevel->window_list);
+ return rc;
+}
+
+static AtkObject*
+gail_toplevel_ref_child (AtkObject *obj,
+ gint i)
+{
+ GailToplevel *toplevel;
+ gpointer ptr;
+ GtkWidget *widget;
+ AtkObject *atk_obj;
+
+ toplevel = GAIL_TOPLEVEL (obj);
+ ptr = g_list_nth_data (toplevel->window_list, i);
+ if (!ptr)
+ return NULL;
+ widget = GTK_WIDGET (ptr);
+ atk_obj = gtk_widget_get_accessible (widget);
+
+ g_object_ref (atk_obj);
+ return atk_obj;
+}
+
+/*
+ * Window destroy events on GtkWindow cause a child to be removed
+ * from the toplevel
+ */
+static void
+gail_toplevel_window_destroyed (GtkWindow *window,
+ GailToplevel *toplevel)
+{
+ _gail_toplevel_remove_child (toplevel, window);
+}
+
+/*
+ * Show events cause a child to be added to the toplevel
+ */
+static gboolean
+gail_toplevel_show_event_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GailToplevel *toplevel = GAIL_TOPLEVEL (data);
+ AtkObject *atk_obj = ATK_OBJECT (toplevel);
+ GObject *object;
+ GtkWidget *widget;
+ gint n_children;
+ AtkObject *child;
+
+ object = g_value_get_object (param_values + 0);
+
+ if (!GTK_IS_WINDOW (object))
+ return TRUE;
+
+ widget = GTK_WIDGET (object);
+ if (gtk_widget_get_parent (widget) ||
+ is_attached_menu_window (widget) ||
+#ifdef GDK_WINDOWING_X11
+ GTK_IS_PLUG (widget) ||
+#endif
+ is_combo_window (widget))
+ return TRUE;
+
+ child = gtk_widget_get_accessible (widget);
+ if (atk_object_get_role (child) == ATK_ROLE_REDUNDANT_OBJECT)
+ {
+ return TRUE;
+ }
+
+ /*
+ * Add the window to the list & emit the signal.
+ * Don't do this for tooltips (Bug #150649).
+ */
+ if (atk_object_get_role (child) == ATK_ROLE_TOOL_TIP)
+ {
+ return TRUE;
+ }
+
+ toplevel->window_list = g_list_append (toplevel->window_list, widget);
+
+ n_children = g_list_length (toplevel->window_list);
+
+ /*
+ * Must subtract 1 from the n_children since the index is 0-based
+ * but g_list_length is 1-based.
+ */
+ atk_object_set_parent (child, atk_obj);
+ g_signal_emit_by_name (atk_obj, "children-changed::add",
+ n_children - 1,
+ child, NULL);
+
+ /* Connect destroy signal callback */
+ g_signal_connect (G_OBJECT(object),
+ "destroy",
+ G_CALLBACK (gail_toplevel_window_destroyed),
+ toplevel);
+
+ return TRUE;
+}
+
+/*
+ * Hide events on GtkWindow cause a child to be removed from the toplevel
+ */
+static gboolean
+gail_toplevel_hide_event_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GailToplevel *toplevel = GAIL_TOPLEVEL (data);
+ GObject *object;
+
+ object = g_value_get_object (param_values + 0);
+
+ if (!GTK_IS_WINDOW (object))
+ return TRUE;
+
+ _gail_toplevel_remove_child (toplevel, GTK_WINDOW (object));
+ return TRUE;
+}
+
+/*
+ * Common code used by destroy and hide events on GtkWindow
+ */
+static void
+_gail_toplevel_remove_child (GailToplevel *toplevel,
+ GtkWindow *window)
+{
+ AtkObject *atk_obj = ATK_OBJECT (toplevel);
+ GList *l;
+ guint window_count = 0;
+ AtkObject *child;
+
+ if (toplevel->window_list)
+ {
+ GtkWindow *tmp_window;
+
+ /* Must loop through them all */
+ for (l = toplevel->window_list; l; l = l->next)
+ {
+ tmp_window = GTK_WINDOW (l->data);
+
+ if (window == tmp_window)
+ {
+ /* Remove the window from the window_list & emit the signal */
+ toplevel->window_list = g_list_remove (toplevel->window_list,
+ l->data);
+ child = gtk_widget_get_accessible (GTK_WIDGET (window));
+ g_signal_emit_by_name (atk_obj, "children-changed::remove",
+ window_count,
+ child, NULL);
+ atk_object_set_parent (child, NULL);
+ break;
+ }
+
+ window_count++;
+ }
+ }
+}
+
+static gboolean
+is_attached_menu_window (GtkWidget *widget)
+{
+ GtkWidget *child;
+ gboolean ret = FALSE;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (GTK_IS_MENU (child))
+ {
+ GtkWidget *attach;
+
+ attach = gtk_menu_get_attach_widget (GTK_MENU (child));
+ /* Allow for menu belonging to the Panel Menu, which is a GtkButton */
+ if (GTK_IS_MENU_ITEM (attach) ||
+ GTK_IS_BUTTON (attach))
+ ret = TRUE;
+ }
+ return ret;
+}
+
+static gboolean
+is_combo_window (GtkWidget *widget)
+{
+ GtkWidget *child;
+ AtkObject *obj;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (!GTK_IS_EVENT_BOX (child))
+ return FALSE;
+
+ child = gtk_bin_get_child (GTK_BIN (child));
+
+ if (!GTK_IS_FRAME (child))
+ return FALSE;
+
+ child = gtk_bin_get_child (GTK_BIN (child));
+
+ if (!GTK_IS_SCROLLED_WINDOW (child))
+ return FALSE;
+
+ obj = gtk_widget_get_accessible (child);
+ obj = atk_object_get_parent (obj);
+
+ return FALSE;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_TOPLEVEL_H__
+#define __GAIL_TOPLEVEL_H__
+
+#include <atk/atk.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_TOPLEVEL (gail_toplevel_get_type ())
+#define GAIL_TOPLEVEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TOPLEVEL, GailToplevel))
+#define GAIL_TOPLEVEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TOPLEVEL, GailToplevelClass))
+#define GAIL_IS_TOPLEVEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TOPLEVEL))
+#define GAIL_IS_TOPLEVEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TOPLEVEL))
+#define GAIL_TOPLEVEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TOPLEVEL, GailToplevelClass))
+
+typedef struct _GailToplevel GailToplevel;
+typedef struct _GailToplevelClass GailToplevelClass;
+
+struct _GailToplevel
+{
+ AtkObject parent;
+ GList *window_list;
+};
+
+GType gail_toplevel_get_type (void);
+
+struct _GailToplevelClass
+{
+ AtkObjectClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_TOPLEVEL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/x11/gdkx.h>
+#endif
+#include "gailtreeview.h"
+#include "gailrenderercell.h"
+#include "gailbooleancell.h"
+#include "gailcontainercell.h"
+#include "gailtextcell.h"
+#include "gailcellparent.h"
+#include "gail-private-macros.h"
+
+typedef struct _GailTreeViewRowInfo GailTreeViewRowInfo;
+typedef struct _GailTreeViewCellInfo GailTreeViewCellInfo;
+
+static void gail_tree_view_class_init (GailTreeViewClass *klass);
+static void gail_tree_view_init (GailTreeView *view);
+static void gail_tree_view_real_initialize (AtkObject *obj,
+ gpointer data);
+static void gail_tree_view_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+static void gail_tree_view_finalize (GObject *object);
+
+static void gail_tree_view_connect_widget_destroyed
+ (GtkAccessible *accessible);
+static void gail_tree_view_destroyed (GtkWidget *widget,
+ GtkAccessible *accessible);
+/* atkobject.h */
+
+static gint gail_tree_view_get_n_children (AtkObject *obj);
+static AtkObject* gail_tree_view_ref_child (AtkObject *obj,
+ gint i);
+static AtkStateSet* gail_tree_view_ref_state_set (AtkObject *obj);
+
+/* atkcomponent.h */
+
+static void atk_component_interface_init (AtkComponentIface *iface);
+
+static AtkObject* gail_tree_view_ref_accessible_at_point
+ (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type);
+
+/* atktable.h */
+
+static void atk_table_interface_init (AtkTableIface *iface);
+
+static gint gail_tree_view_get_index_at (AtkTable *table,
+ gint row,
+ gint column);
+static gint gail_tree_view_get_column_at_index
+ (AtkTable *table,
+ gint index);
+static gint gail_tree_view_get_row_at_index (AtkTable *table,
+ gint index);
+
+static AtkObject* gail_tree_view_table_ref_at (AtkTable *table,
+ gint row,
+ gint column);
+static gint gail_tree_view_get_n_rows (AtkTable *table);
+static gint gail_tree_view_get_n_columns (AtkTable *table);
+static gint get_n_actual_columns (GtkTreeView *tree_view);
+static gboolean gail_tree_view_is_row_selected (AtkTable *table,
+ gint row);
+static gboolean gail_tree_view_is_selected (AtkTable *table,
+ gint row,
+ gint column);
+static gint gail_tree_view_get_selected_rows
+ (AtkTable *table,
+ gint **selected);
+static gboolean gail_tree_view_add_row_selection
+ (AtkTable *table,
+ gint row);
+static gboolean gail_tree_view_remove_row_selection
+ (AtkTable *table,
+ gint row);
+static AtkObject* gail_tree_view_get_row_header (AtkTable *table,
+ gint row);
+static AtkObject* gail_tree_view_get_column_header
+ (AtkTable *table,
+ gint column);
+static void gail_tree_view_set_row_header (AtkTable *table,
+ gint row,
+ AtkObject *header);
+static void gail_tree_view_set_column_header
+ (AtkTable *table,
+ gint column,
+ AtkObject *header);
+static AtkObject*
+ gail_tree_view_get_caption (AtkTable *table);
+static void gail_tree_view_set_caption (AtkTable *table,
+ AtkObject *caption);
+static AtkObject* gail_tree_view_get_summary (AtkTable *table);
+static void gail_tree_view_set_summary (AtkTable *table,
+ AtkObject *accessible);
+static const gchar*
+ gail_tree_view_get_row_description
+ (AtkTable *table,
+ gint row);
+static void gail_tree_view_set_row_description
+ (AtkTable *table,
+ gint row,
+ const gchar *description);
+static const gchar*
+ gail_tree_view_get_column_description
+ (AtkTable *table,
+ gint column);
+static void gail_tree_view_set_column_description
+ (AtkTable *table,
+ gint column,
+ const gchar *description);
+
+static void set_row_data (AtkTable *table,
+ gint row,
+ AtkObject *header,
+ const gchar *description,
+ gboolean is_header);
+static GailTreeViewRowInfo*
+ get_row_info (AtkTable *table,
+ gint row);
+
+/* atkselection.h */
+
+static void atk_selection_interface_init (AtkSelectionIface *iface);
+static gboolean gail_tree_view_add_selection (AtkSelection *selection,
+ gint i);
+static gboolean gail_tree_view_clear_selection (AtkSelection *selection);
+static AtkObject* gail_tree_view_ref_selection (AtkSelection *selection,
+ gint i);
+static gint gail_tree_view_get_selection_count
+ (AtkSelection *selection);
+static gboolean gail_tree_view_is_child_selected
+ (AtkSelection *selection,
+ gint i);
+
+/* gailcellparent.h */
+
+static void gail_cell_parent_interface_init (GailCellParentIface *iface);
+static void gail_tree_view_get_cell_extents (GailCellParent *parent,
+ GailCell *cell,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+static void gail_tree_view_get_cell_area (GailCellParent *parent,
+ GailCell *cell,
+ GdkRectangle *cell_rect);
+static gboolean gail_tree_view_grab_cell_focus (GailCellParent *parent,
+ GailCell *cell);
+
+/* signal handling */
+
+static gboolean gail_tree_view_expand_row_gtk (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path);
+static gint idle_expand_row (gpointer data);
+static gboolean gail_tree_view_collapse_row_gtk (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path);
+static void gail_tree_view_size_allocate_gtk (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void gail_tree_view_changed_gtk (GtkTreeSelection *selection,
+ gpointer data);
+
+static void columns_changed (GtkTreeView *tree_view);
+static void cursor_changed (GtkTreeView *tree_view);
+static gint idle_cursor_changed (gpointer data);
+static gboolean focus_in (GtkWidget *widget);
+static gboolean focus_out (GtkWidget *widget);
+
+static void model_row_changed (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data);
+static void column_visibility_changed (GObject *object,
+ GParamSpec *param,
+ gpointer user_data);
+static void model_row_inserted (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data);
+static void model_row_deleted (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ gpointer user_data);
+static void destroy_count_func (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ gint count,
+ gpointer user_data);
+static void model_rows_reordered (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gint *new_order,
+ gpointer user_data);
+static void adjustment_changed (GtkAdjustment *adjustment,
+ GtkTreeView *tree_view);
+
+/* Misc */
+
+static void set_iter_nth_row (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ gint row);
+static gint get_row_from_tree_path (GtkTreeView *tree_view,
+ GtkTreePath *path);
+static GtkTreeViewColumn* get_column (GtkTreeView *tree_view,
+ gint in_col);
+static gint get_actual_column_number (GtkTreeView *tree_view,
+ gint visible_column);
+static gint get_visible_column_number (GtkTreeView *tree_view,
+ gint actual_column);
+static void iterate_thru_children (GtkTreeView *tree_view,
+ GtkTreeModel *tree_model,
+ GtkTreePath *tree_path,
+ GtkTreePath *orig,
+ gint *count,
+ gint depth);
+static GtkTreeIter* return_iter_nth_row (GtkTreeView *tree_view,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gint increment,
+ gint row);
+static void free_row_info (GArray *array,
+ gint array_idx,
+ gboolean shift);
+static void clean_cell_info (GailTreeView *tree_view,
+ GList *list);
+static void clean_rows (GailTreeView *tree_view);
+static void clean_cols (GailTreeView *tree_view,
+ GtkTreeViewColumn *tv_col);
+static void traverse_cells (GailTreeView *tree_view,
+ GtkTreePath *tree_path,
+ gboolean set_stale,
+ gboolean inc_row);
+static gboolean update_cell_value (GailRendererCell *renderer_cell,
+ GailTreeView *gailview,
+ gboolean emit_change_signal);
+static void set_cell_visibility (GtkTreeView *tree_view,
+ GailCell *cell,
+ GtkTreeViewColumn *tv_col,
+ GtkTreePath *tree_path,
+ gboolean emit_signal);
+static gboolean is_cell_showing (GtkTreeView *tree_view,
+ GdkRectangle *cell_rect);
+static void set_expand_state (GtkTreeView *tree_view,
+ GtkTreeModel *tree_model,
+ GailTreeView *gailview,
+ GtkTreePath *tree_path,
+ gboolean set_on_ancestor);
+static void add_cell_actions (GailCell *cell,
+ gboolean editable);
+
+static void toggle_cell_expanded (GailCell *cell);
+static void toggle_cell_toggled (GailCell *cell);
+static void edit_cell (GailCell *cell);
+static void activate_cell (GailCell *cell);
+static void cell_destroyed (gpointer data);
+#if 0
+static void cell_info_remove (GailTreeView *tree_view,
+ GailCell *cell);
+#endif
+static void cell_info_get_index (GtkTreeView *tree_view,
+ GailTreeViewCellInfo *info,
+ gint *index);
+static void cell_info_new (GailTreeView *gailview,
+ GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeViewColumn *tv_col,
+ GailCell *cell);
+static GailCell* find_cell (GailTreeView *gailview,
+ gint index);
+static void refresh_cell_index (GailCell *cell);
+static void get_selected_rows (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data);
+static void connect_model_signals (GtkTreeView *view,
+ GailTreeView *gailview);
+static void disconnect_model_signals (GailTreeView *gailview);
+static void clear_cached_data (GailTreeView *view);
+static gint get_column_number (GtkTreeView *tree_view,
+ GtkTreeViewColumn *column,
+ gboolean visible);
+static gint get_focus_index (GtkTreeView *tree_view);
+static gint get_index (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ gint actual_column);
+static void count_rows (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkTreePath *end_path,
+ gint *count,
+ gint level,
+ gint depth);
+
+static gboolean get_next_node_with_child_at_depth
+ (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkTreePath **path,
+ gint level,
+ gint depth);
+static gboolean get_next_node_with_child (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreePath **return_path);
+static gboolean get_tree_path_from_row_index (GtkTreeModel *model,
+ gint row_index,
+ GtkTreePath **tree_path);
+static gint get_row_count (GtkTreeModel *model);
+static gboolean get_path_column_from_index (GtkTreeView *tree_view,
+ gint index,
+ GtkTreePath **path,
+ GtkTreeViewColumn **column);
+static void set_cell_expandable (GailCell *cell);
+
+static GailTreeViewCellInfo* find_cell_info (GailTreeView *view,
+ GailCell *cell,
+ GList** list,
+ gboolean live_only);
+static AtkObject * get_header_from_column (GtkTreeViewColumn *tv_col);
+static gboolean idle_garbage_collect_cell_data (gpointer data);
+static gboolean garbage_collect_cell_data (gpointer data);
+
+static GQuark quark_column_desc_object = 0;
+static GQuark quark_column_header_object = 0;
+static gboolean editing = FALSE;
+
+struct _GailTreeViewRowInfo
+{
+ GtkTreeRowReference *row_ref;
+ gchar *description;
+ AtkObject *header;
+};
+
+struct _GailTreeViewCellInfo
+{
+ GailCell *cell;
+ GtkTreeRowReference *cell_row_ref;
+ GtkTreeViewColumn *cell_col_ref;
+ GailTreeView *view;
+ gboolean in_use;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GailTreeView, gail_tree_view, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_TABLE, atk_table_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init)
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)
+ G_IMPLEMENT_INTERFACE (GAIL_TYPE_CELL_PARENT, gail_cell_parent_interface_init))
+
+static void
+gail_tree_view_class_init (GailTreeViewClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkAccessibleClass *accessible_class;
+ GailWidgetClass *widget_class;
+ GailContainerClass *container_class;
+
+ accessible_class = (GtkAccessibleClass*)klass;
+ widget_class = (GailWidgetClass*)klass;
+ container_class = (GailContainerClass*)klass;
+
+ class->get_n_children = gail_tree_view_get_n_children;
+ class->ref_child = gail_tree_view_ref_child;
+ class->ref_state_set = gail_tree_view_ref_state_set;
+ class->initialize = gail_tree_view_real_initialize;
+
+ widget_class->notify_gtk = gail_tree_view_real_notify_gtk;
+
+ accessible_class->connect_widget_destroyed = gail_tree_view_connect_widget_destroyed;
+
+ /*
+ * The children of a GtkTreeView are the buttons at the top of the columns
+ * we do not represent these as children so we do not want to report
+ * children added or deleted when these changed.
+ */
+ container_class->add_gtk = NULL;
+ container_class->remove_gtk = NULL;
+
+ gobject_class->finalize = gail_tree_view_finalize;
+
+ quark_column_desc_object = g_quark_from_static_string ("gtk-column-object");
+ quark_column_header_object = g_quark_from_static_string ("gtk-header-object");
+}
+
+static void
+gail_tree_view_init (GailTreeView *view)
+{
+}
+
+static void
+gail_tree_view_hadjustment_set (GObject *widget,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ GtkAdjustment *adj;
+ GailTreeView *view = data;
+
+ g_object_get (widget, "hadjustment", &adj, NULL);
+ view->old_hadj = adj;
+ g_object_add_weak_pointer (G_OBJECT (view->old_hadj), (gpointer *)&view->old_hadj);
+ g_signal_connect (adj,
+ "value-changed",
+ G_CALLBACK (adjustment_changed),
+ widget);
+}
+
+static void
+gail_tree_view_vadjustment_set (GObject *widget,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ GtkAdjustment *adj;
+ GailTreeView *view = data;
+
+ g_object_get (widget, "vadjustment", &adj, NULL);
+ view->old_vadj = adj;
+ g_object_add_weak_pointer (G_OBJECT (view->old_vadj), (gpointer *)&view->old_vadj);
+ g_signal_connect (adj,
+ "value-changed",
+ G_CALLBACK (adjustment_changed),
+ widget);
+}
+
+static void
+gail_tree_view_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GailTreeView *view;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+ GList *tv_cols, *tmp_list;
+ GtkWidget *widget;
+
+ ATK_OBJECT_CLASS (gail_tree_view_parent_class)->initialize (obj, data);
+
+ view = GAIL_TREE_VIEW (obj);
+ view->caption = NULL;
+ view->summary = NULL;
+ view->row_data = NULL;
+ view->col_data = NULL;
+ view->cell_data = NULL;
+ view->focus_cell = NULL;
+ view->old_hadj = NULL;
+ view->old_vadj = NULL;
+ view->idle_expand_id = 0;
+ view->idle_expand_path = NULL;
+
+ view->n_children_deleted = 0;
+
+ widget = GTK_WIDGET (data);
+ g_signal_connect_after (widget,
+ "row-collapsed",
+ G_CALLBACK (gail_tree_view_collapse_row_gtk),
+ NULL);
+ g_signal_connect (widget,
+ "row-expanded",
+ G_CALLBACK (gail_tree_view_expand_row_gtk),
+ NULL);
+ g_signal_connect (widget,
+ "size-allocate",
+ G_CALLBACK (gail_tree_view_size_allocate_gtk),
+ NULL);
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+
+ /* Set up signal handling */
+
+ g_signal_connect_data (gtk_tree_view_get_selection (tree_view),
+ "changed",
+ (GCallback) gail_tree_view_changed_gtk,
+ obj, NULL, 0);
+
+ g_signal_connect_data (tree_view, "columns-changed",
+ (GCallback) columns_changed, NULL, NULL, 0);
+ g_signal_connect_data (tree_view, "cursor-changed",
+ (GCallback) cursor_changed, NULL, NULL, 0);
+ g_signal_connect_data (GTK_WIDGET (tree_view), "focus-in-event",
+ (GCallback) focus_in, NULL, NULL, 0);
+ g_signal_connect_data (GTK_WIDGET (tree_view), "focus-out-event",
+ (GCallback) focus_out, NULL, NULL, 0);
+
+ view->tree_model = tree_model;
+ if (tree_model)
+ {
+ g_object_add_weak_pointer (G_OBJECT (view->tree_model), (gpointer *)&view->tree_model);
+ connect_model_signals (tree_view, view);
+
+ if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
+ obj->role = ATK_ROLE_TABLE;
+ else
+ obj->role = ATK_ROLE_TREE_TABLE;
+ }
+ else
+ {
+ obj->role = ATK_ROLE_UNKNOWN;
+ }
+
+ /* adjustment callbacks */
+
+ gail_tree_view_hadjustment_set (G_OBJECT (widget), NULL, view);
+ gail_tree_view_vadjustment_set (G_OBJECT (widget), NULL, view);
+ g_signal_connect (widget,
+ "notify::hadjustment",
+ G_CALLBACK (gail_tree_view_hadjustment_set),
+ view);
+ g_signal_connect (widget,
+ "notify::vadjustment",
+ G_CALLBACK (gail_tree_view_vadjustment_set),
+ view);
+
+ view->col_data = g_array_sized_new (FALSE, TRUE,
+ sizeof(GtkTreeViewColumn *), 0);
+
+ tv_cols = gtk_tree_view_get_columns (tree_view);
+
+ for (tmp_list = tv_cols; tmp_list; tmp_list = tmp_list->next)
+ {
+ g_signal_connect_data (tmp_list->data, "notify::visible",
+ (GCallback)column_visibility_changed,
+ tree_view, NULL, FALSE);
+ g_array_append_val (view->col_data, tmp_list->data);
+ }
+
+ gtk_tree_view_set_destroy_count_func (tree_view,
+ destroy_count_func,
+ NULL, NULL);
+ g_list_free (tv_cols);
+}
+
+static void
+gail_tree_view_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkWidget *widget;
+ AtkObject* atk_obj;
+ GtkTreeView *tree_view;
+ GailTreeView *gailview;
+ GtkAdjustment *adj;
+
+ widget = GTK_WIDGET (obj);
+ atk_obj = gtk_widget_get_accessible (widget);
+ tree_view = GTK_TREE_VIEW (widget);
+ gailview = GAIL_TREE_VIEW (atk_obj);
+
+ if (strcmp (pspec->name, "model") == 0)
+ {
+ GtkTreeModel *tree_model;
+ AtkRole role;
+
+ tree_model = gtk_tree_view_get_model (tree_view);
+ if (gailview->tree_model)
+ disconnect_model_signals (gailview);
+ clear_cached_data (gailview);
+ gailview->tree_model = tree_model;
+ /*
+ * if there is no model the GtkTreeView is probably being destroyed
+ */
+ if (tree_model)
+ {
+ g_object_add_weak_pointer (G_OBJECT (gailview->tree_model), (gpointer *)&gailview->tree_model);
+ connect_model_signals (tree_view, gailview);
+
+ if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
+ role = ATK_ROLE_TABLE;
+ else
+ role = ATK_ROLE_TREE_TABLE;
+ }
+ else
+ {
+ role = ATK_ROLE_UNKNOWN;
+ }
+ atk_object_set_role (atk_obj, role);
+ g_object_freeze_notify (G_OBJECT (atk_obj));
+ g_signal_emit_by_name (atk_obj, "model_changed");
+ g_signal_emit_by_name (atk_obj, "visible_data_changed");
+ g_object_thaw_notify (G_OBJECT (atk_obj));
+ }
+ else if (strcmp (pspec->name, "hadjustment") == 0)
+ {
+ g_object_get (tree_view, "hadjustment", &adj, NULL);
+ g_signal_handlers_disconnect_by_func (gailview->old_hadj,
+ (gpointer) adjustment_changed,
+ widget);
+ gailview->old_hadj = adj;
+ g_object_add_weak_pointer (G_OBJECT (gailview->old_hadj), (gpointer *)&gailview->old_hadj);
+ g_signal_connect (adj,
+ "value-changed",
+ G_CALLBACK (adjustment_changed),
+ tree_view);
+ }
+ else if (strcmp (pspec->name, "vadjustment") == 0)
+ {
+ g_object_get (tree_view, "vadjustment", &adj, NULL);
+ g_signal_handlers_disconnect_by_func (gailview->old_vadj,
+ (gpointer) adjustment_changed,
+ widget);
+ gailview->old_vadj = adj;
+ g_object_add_weak_pointer (G_OBJECT (gailview->old_hadj), (gpointer *)&gailview->old_vadj);
+ g_signal_connect (adj,
+ "value-changed",
+ G_CALLBACK (adjustment_changed),
+ tree_view);
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_tree_view_parent_class)->notify_gtk (obj, pspec);
+}
+
+static void
+gail_tree_view_finalize (GObject *object)
+{
+ GailTreeView *view = GAIL_TREE_VIEW (object);
+
+ clear_cached_data (view);
+
+ /* remove any idle handlers still pending */
+ if (view->idle_garbage_collect_id)
+ g_source_remove (view->idle_garbage_collect_id);
+ if (view->idle_cursor_changed_id)
+ g_source_remove (view->idle_cursor_changed_id);
+ if (view->idle_expand_id)
+ g_source_remove (view->idle_expand_id);
+
+ if (view->caption)
+ g_object_unref (view->caption);
+ if (view->summary)
+ g_object_unref (view->summary);
+
+ if (view->tree_model)
+ disconnect_model_signals (view);
+
+ if (view->col_data)
+ {
+ GArray *array = view->col_data;
+
+ /*
+ * No need to free the contents of the array since it
+ * just contains pointers to the GtkTreeViewColumn
+ * objects that are in the GtkTreeView.
+ */
+ g_array_free (array, TRUE);
+ }
+
+ G_OBJECT_CLASS (gail_tree_view_parent_class)->finalize (object);
+}
+
+static void
+gail_tree_view_connect_widget_destroyed (GtkAccessible *accessible)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget)
+ {
+ g_signal_connect_after (widget,
+ "destroy",
+ G_CALLBACK (gail_tree_view_destroyed),
+ accessible);
+ }
+ GTK_ACCESSIBLE_CLASS (gail_tree_view_parent_class)->connect_widget_destroyed (accessible);
+}
+
+static void
+gail_tree_view_destroyed (GtkWidget *widget,
+ GtkAccessible *accessible)
+{
+ GtkAdjustment *adj;
+ GailTreeView *gailview;
+
+ gail_return_if_fail (GTK_IS_TREE_VIEW (widget));
+
+ gailview = GAIL_TREE_VIEW (accessible);
+ adj = gailview->old_hadj;
+ if (adj)
+ g_signal_handlers_disconnect_by_func (adj,
+ (gpointer) adjustment_changed,
+ widget);
+ adj = gailview->old_vadj;
+ if (adj)
+ g_signal_handlers_disconnect_by_func (adj,
+ (gpointer) adjustment_changed,
+ widget);
+ if (gailview->tree_model)
+ {
+ disconnect_model_signals (gailview);
+ gailview->tree_model = NULL;
+ }
+ if (gailview->focus_cell)
+ {
+ g_object_unref (gailview->focus_cell);
+ gailview->focus_cell = NULL;
+ }
+ if (gailview->idle_expand_id)
+ {
+ g_source_remove (gailview->idle_expand_id);
+ gailview->idle_expand_id = 0;
+ }
+}
+
+gint
+get_focus_index (GtkTreeView *tree_view)
+{
+ GtkTreePath *focus_path;
+ GtkTreeViewColumn *focus_column;
+ gint index;
+
+ gtk_tree_view_get_cursor (tree_view, &focus_path, &focus_column);
+ if (focus_path && focus_column)
+ {
+
+ index = get_index (tree_view, focus_path,
+ get_column_number (tree_view, focus_column, FALSE));
+ }
+ else
+ index = -1;
+
+ if (focus_path)
+ gtk_tree_path_free (focus_path);
+
+ return index;
+}
+
+AtkObject *
+gail_tree_view_ref_focus_cell (GtkTreeView *tree_view)
+{
+ /*
+ * This function returns a reference to the accessible object for the cell
+ * in the treeview which has focus, if a cell has focus.
+ */
+ AtkObject *focus_cell = NULL;
+ AtkObject *atk_obj;
+ gint focus_index;
+
+ focus_index = get_focus_index (tree_view);
+ if (focus_index >= 0)
+ {
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
+ focus_cell = atk_object_ref_accessible_child (atk_obj, focus_index);
+ }
+
+ return focus_cell;
+}
+
+/* atkobject.h */
+
+static gint
+gail_tree_view_get_n_children (AtkObject *obj)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+ gint n_rows, n_cols;
+
+ gail_return_val_if_fail (GAIL_IS_TREE_VIEW (obj), 0);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return 0;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+
+ /*
+ * We get the total number of rows including those which are collapsed
+ */
+ n_rows = get_row_count (tree_model);
+ /*
+ * We get the total number of columns including those which are not visible
+ */
+ n_cols = get_n_actual_columns (tree_view);
+ return (n_rows * n_cols);
+}
+
+static AtkObject*
+gail_tree_view_ref_child (AtkObject *obj,
+ gint i)
+{
+ GtkWidget *widget;
+ GailTreeView *gailview;
+ GailCell *cell;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+ GtkCellRenderer *renderer;
+ GtkTreeIter iter;
+ GtkTreeViewColumn *tv_col;
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+ AtkRegistry *default_registry;
+ AtkObjectFactory *factory;
+ AtkObject *child;
+ AtkObject *parent;
+ GtkTreeViewColumn *expander_tv;
+ GList *renderer_list;
+ GList *l;
+ GailContainerCell *container = NULL;
+ GailRendererCell *renderer_cell;
+ gboolean is_expander, is_expanded, retval;
+ gboolean editable = FALSE;
+ gint focus_index;
+
+ g_return_val_if_fail (GAIL_IS_TREE_VIEW (obj), NULL);
+ g_return_val_if_fail (i >= 0, NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ if (i >= gail_tree_view_get_n_children (obj))
+ return NULL;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ if (i < get_n_actual_columns (tree_view))
+ {
+ tv_col = gtk_tree_view_get_column (tree_view, i);
+ child = get_header_from_column (tv_col);
+ if (child)
+ g_object_ref (child);
+ return child;
+ }
+
+ gailview = GAIL_TREE_VIEW (obj);
+ /*
+ * Check whether the child is cached
+ */
+ cell = find_cell (gailview, i);
+ if (cell)
+ {
+ g_object_ref (cell);
+ return ATK_OBJECT (cell);
+ }
+
+ if (gailview->focus_cell == NULL)
+ focus_index = get_focus_index (tree_view);
+ else
+ focus_index = -1;
+ /*
+ * Find the TreePath and GtkTreeViewColumn for the index
+ */
+ if (!get_path_column_from_index (tree_view, i, &path, &tv_col))
+ return NULL;
+
+ tree_model = gtk_tree_view_get_model (tree_view);
+ retval = gtk_tree_model_get_iter (tree_model, &iter, path);
+ gail_return_val_if_fail (retval, NULL);
+
+ expander_tv = gtk_tree_view_get_expander_column (tree_view);
+ is_expander = FALSE;
+ is_expanded = FALSE;
+ if (gtk_tree_model_iter_has_child (tree_model, &iter))
+ {
+ if (expander_tv == tv_col)
+ {
+ is_expander = TRUE;
+ is_expanded = gtk_tree_view_row_expanded (tree_view, path);
+ }
+ }
+ gtk_tree_view_column_cell_set_cell_data (tv_col, tree_model, &iter,
+ is_expander, is_expanded);
+
+ renderer_list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tv_col));
+
+ /* If there are more than one renderer in the list, make a container */
+
+ if (renderer_list && renderer_list->next)
+ {
+ GailCell *container_cell;
+
+ container = gail_container_cell_new ();
+ gail_return_val_if_fail (container, NULL);
+
+ container_cell = GAIL_CELL (container);
+ gail_cell_initialise (container_cell,
+ widget, ATK_OBJECT (gailview),
+ i);
+ /*
+ * The GailTreeViewCellInfo structure for the container will be before
+ * the ones for the cells so that the first one we find for a position
+ * will be for the container
+ */
+ cell_info_new (gailview, tree_model, path, tv_col, container_cell);
+ container_cell->refresh_index = refresh_cell_index;
+ parent = ATK_OBJECT (container);
+ }
+ else
+ parent = ATK_OBJECT (gailview);
+
+ child = NULL;
+
+ /*
+ * Now we make a fake cell_renderer if there is no cell in renderer_list
+ */
+
+ if (renderer_list == NULL)
+ {
+ GtkCellRenderer *fake_renderer;
+ fake_renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT, NULL);
+ default_registry = atk_get_default_registry ();
+ factory = atk_registry_get_factory (default_registry,
+ G_OBJECT_TYPE (fake_renderer));
+ child = atk_object_factory_create_accessible (factory,
+ G_OBJECT (fake_renderer));
+ gail_return_val_if_fail (GAIL_IS_RENDERER_CELL (child), NULL);
+ cell = GAIL_CELL (child);
+ renderer_cell = GAIL_RENDERER_CELL (child);
+ renderer_cell->renderer = fake_renderer;
+
+ /* Create the GailTreeViewCellInfo structure for this cell */
+ cell_info_new (gailview, tree_model, path, tv_col, cell);
+
+ gail_cell_initialise (cell,
+ widget, parent,
+ i);
+
+ cell->refresh_index = refresh_cell_index;
+
+ /* set state if it is expandable */
+ if (is_expander)
+ {
+ set_cell_expandable (cell);
+ if (is_expanded)
+ gail_cell_add_state (cell,
+ ATK_STATE_EXPANDED,
+ FALSE);
+ }
+ } else {
+ for (l = renderer_list; l; l = l->next)
+ {
+ renderer = GTK_CELL_RENDERER (l->data);
+
+ if (GTK_IS_CELL_RENDERER_TEXT (renderer))
+ g_object_get (G_OBJECT (renderer), "editable", &editable, NULL);
+
+ default_registry = atk_get_default_registry ();
+ factory = atk_registry_get_factory (default_registry,
+ G_OBJECT_TYPE (renderer));
+ child = atk_object_factory_create_accessible (factory,
+ G_OBJECT (renderer));
+ gail_return_val_if_fail (GAIL_IS_RENDERER_CELL (child), NULL);
+ cell = GAIL_CELL (child);
+ renderer_cell = GAIL_RENDERER_CELL (child);
+
+ /* Create the GailTreeViewCellInfo structure for this cell */
+ cell_info_new (gailview, tree_model, path, tv_col, cell);
+
+ gail_cell_initialise (cell,
+ widget, parent,
+ i);
+
+ if (container)
+ gail_container_cell_add_child (container, cell);
+ else
+ cell->refresh_index = refresh_cell_index;
+
+ update_cell_value (renderer_cell, gailview, FALSE);
+ /* Add the actions appropriate for this cell */
+ add_cell_actions (cell, editable);
+
+ /* set state if it is expandable */
+ if (is_expander)
+ {
+ set_cell_expandable (cell);
+ if (is_expanded)
+ gail_cell_add_state (cell,
+ ATK_STATE_EXPANDED,
+ FALSE);
+ }
+ /*
+ * If the column is visible, sets the cell's state
+ */
+ if (gtk_tree_view_column_get_visible (tv_col))
+ set_cell_visibility (tree_view, cell, tv_col, path, FALSE);
+ /*
+ * If the row is selected, all cells on the row are selected
+ */
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gtk_tree_selection_path_is_selected (selection, path))
+ gail_cell_add_state (cell, ATK_STATE_SELECTED, FALSE);
+
+ gail_cell_add_state (cell, ATK_STATE_FOCUSABLE, FALSE);
+ if (focus_index == i)
+ {
+ gailview->focus_cell = g_object_ref (cell);
+ gail_cell_add_state (cell, ATK_STATE_FOCUSED, FALSE);
+ g_signal_emit_by_name (gailview,
+ "active-descendant-changed",
+ cell);
+ }
+ }
+ g_list_free (renderer_list);
+ if (container)
+ child = ATK_OBJECT (container);
+ }
+
+ if (expander_tv == tv_col)
+ {
+ AtkRelationSet *relation_set;
+ AtkObject *accessible_array[1];
+ AtkRelation* relation;
+ AtkObject *parent_node;
+
+ relation_set = atk_object_ref_relation_set (ATK_OBJECT (child));
+
+ gtk_tree_path_up (path);
+ if (gtk_tree_path_get_depth (path) == 0)
+ parent_node = obj;
+ else
+ {
+ gint parent_index;
+ gint n_columns;
+
+ n_columns = get_n_actual_columns (tree_view);
+ parent_index = get_index (tree_view, path, i % n_columns);
+ parent_node = atk_object_ref_accessible_child (obj, parent_index);
+ }
+ accessible_array[0] = parent_node;
+ relation = atk_relation_new (accessible_array, 1,
+ ATK_RELATION_NODE_CHILD_OF);
+ atk_relation_set_add (relation_set, relation);
+ atk_object_add_relationship (parent_node, ATK_RELATION_NODE_PARENT_OF,
+ child);
+ g_object_unref (relation);
+ g_object_unref (relation_set);
+ }
+ gtk_tree_path_free (path);
+
+ /*
+ * We do not increase the reference count here; when g_object_unref() is
+ * called for the cell then cell_destroyed() is called and
+ * this removes the cell from the cache.
+ */
+ return child;
+}
+
+static AtkStateSet*
+gail_tree_view_ref_state_set (AtkObject *obj)
+{
+ AtkStateSet *state_set;
+ GtkWidget *widget;
+
+ state_set = ATK_OBJECT_CLASS (gail_tree_view_parent_class)->ref_state_set (obj);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+
+ if (widget != NULL)
+ atk_state_set_add_state (state_set, ATK_STATE_MANAGES_DESCENDANTS);
+
+ return state_set;
+}
+
+/* atkcomponent.h */
+
+static void
+atk_component_interface_init (AtkComponentIface *iface)
+{
+ iface->ref_accessible_at_point = gail_tree_view_ref_accessible_at_point;
+}
+
+static AtkObject*
+gail_tree_view_ref_accessible_at_point (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreePath *path;
+ GtkTreeViewColumn *tv_column;
+ gint x_pos, y_pos;
+ gint bx, by;
+ gboolean ret_val;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ tree_view = GTK_TREE_VIEW (widget);
+
+ atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type);
+ gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, &bx, &by);
+ ret_val = gtk_tree_view_get_path_at_pos (tree_view,
+ bx - x_pos, by - y_pos,
+ &path, &tv_column, NULL, NULL);
+ if (ret_val)
+ {
+ gint index, column;
+
+ column = get_column_number (tree_view, tv_column, FALSE);
+ index = get_index (tree_view, path, column);
+ gtk_tree_path_free (path);
+
+ return gail_tree_view_ref_child (ATK_OBJECT (component), index);
+ }
+ else
+ {
+ g_warning ("gail_tree_view_ref_accessible_at_point: gtk_tree_view_get_path_at_pos () failed\n");
+ }
+ return NULL;
+}
+
+/* atktable.h */
+
+static void
+atk_table_interface_init (AtkTableIface *iface)
+{
+ iface->ref_at = gail_tree_view_table_ref_at;
+ iface->get_n_rows = gail_tree_view_get_n_rows;
+ iface->get_n_columns = gail_tree_view_get_n_columns;
+ iface->get_index_at = gail_tree_view_get_index_at;
+ iface->get_column_at_index = gail_tree_view_get_column_at_index;
+ iface->get_row_at_index = gail_tree_view_get_row_at_index;
+ iface->is_row_selected = gail_tree_view_is_row_selected;
+ iface->is_selected = gail_tree_view_is_selected;
+ iface->get_selected_rows = gail_tree_view_get_selected_rows;
+ iface->add_row_selection = gail_tree_view_add_row_selection;
+ iface->remove_row_selection = gail_tree_view_remove_row_selection;
+ iface->get_column_extent_at = NULL;
+ iface->get_row_extent_at = NULL;
+ iface->get_row_header = gail_tree_view_get_row_header;
+ iface->set_row_header = gail_tree_view_set_row_header;
+ iface->get_column_header = gail_tree_view_get_column_header;
+ iface->set_column_header = gail_tree_view_set_column_header;
+ iface->get_caption = gail_tree_view_get_caption;
+ iface->set_caption = gail_tree_view_set_caption;
+ iface->get_summary = gail_tree_view_get_summary;
+ iface->set_summary = gail_tree_view_set_summary;
+ iface->get_row_description = gail_tree_view_get_row_description;
+ iface->set_row_description = gail_tree_view_set_row_description;
+ iface->get_column_description = gail_tree_view_get_column_description;
+ iface->set_column_description = gail_tree_view_set_column_description;
+}
+
+static gint
+gail_tree_view_get_index_at (AtkTable *table,
+ gint row,
+ gint column)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ gint actual_column;
+ gint n_cols, n_rows;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ gint index;
+
+ n_cols = atk_table_get_n_columns (table);
+ n_rows = atk_table_get_n_rows (table);
+
+ if (row >= n_rows ||
+ column >= n_cols)
+ return -1;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ actual_column = get_actual_column_number (tree_view, column);
+
+ set_iter_nth_row (tree_view, &iter, row);
+ path = gtk_tree_model_get_path (gtk_tree_view_get_model (tree_view), &iter);
+
+ index = get_index (tree_view, path, actual_column);
+ gtk_tree_path_free (path);
+
+ return index;
+}
+
+static gint
+gail_tree_view_get_column_at_index (AtkTable *table,
+ gint index)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ gint n_columns;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ n_columns = get_n_actual_columns (tree_view);
+
+ if (n_columns == 0)
+ return 0;
+ index = index % n_columns;
+
+ return get_visible_column_number (tree_view, index);
+}
+
+static gint
+gail_tree_view_get_row_at_index (AtkTable *table,
+ gint index)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreePath *path;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return -1;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ if (get_path_column_from_index (tree_view, index, &path, NULL))
+ {
+ gint row = get_row_from_tree_path (tree_view, path);
+ gtk_tree_path_free (path);
+ return row;
+ }
+ else
+ return -1;
+}
+
+static AtkObject*
+gail_tree_view_table_ref_at (AtkTable *table,
+ gint row,
+ gint column)
+{
+ gint index;
+
+ index = gail_tree_view_get_index_at (table, row, column);
+ if (index == -1)
+ return NULL;
+
+ return gail_tree_view_ref_child (ATK_OBJECT (table), index);
+}
+
+static gint
+gail_tree_view_get_n_rows (AtkTable *table)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+ gint n_rows;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+
+ if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
+ /*
+ * If working with a LIST store, then this is a faster way
+ * to get the number of rows.
+ */
+ n_rows = gtk_tree_model_iter_n_children (tree_model, NULL);
+ else
+ {
+ GtkTreePath *root_tree;
+
+ n_rows = 0;
+ root_tree = gtk_tree_path_new_first ();
+ iterate_thru_children (tree_view, tree_model,
+ root_tree, NULL, &n_rows, 0);
+ gtk_tree_path_free (root_tree);
+ }
+
+ return n_rows;
+}
+
+/*
+ * The function get_n_actual_columns returns the number of columns in the
+ * GtkTreeView. i.e. it include both visible and non-visible columns.
+ */
+static gint
+get_n_actual_columns (GtkTreeView *tree_view)
+{
+ GList *columns;
+ gint n_cols;
+
+ columns = gtk_tree_view_get_columns (tree_view);
+ n_cols = g_list_length (columns);
+ g_list_free (columns);
+ return n_cols;
+}
+
+static gint
+gail_tree_view_get_n_columns (AtkTable *table)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *tv_col;
+ gint n_cols = 0;
+ gint i = 0;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tv_col = gtk_tree_view_get_column (tree_view, i);
+
+ while (tv_col != NULL)
+ {
+ if (gtk_tree_view_column_get_visible (tv_col))
+ n_cols++;
+
+ i++;
+ tv_col = gtk_tree_view_get_column (tree_view, i);
+ }
+
+ return n_cols;
+}
+
+static gboolean
+gail_tree_view_is_row_selected (AtkTable *table,
+ gint row)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ if (row < 0)
+ return FALSE;
+
+ tree_view = GTK_TREE_VIEW (widget);
+
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ set_iter_nth_row (tree_view, &iter, row);
+
+ return gtk_tree_selection_iter_is_selected (selection, &iter);
+}
+
+static gboolean
+gail_tree_view_is_selected (AtkTable *table,
+ gint row,
+ gint column)
+{
+ return gail_tree_view_is_row_selected (table, row);
+}
+
+static gint
+gail_tree_view_get_selected_rows (AtkTable *table,
+ gint **rows_selected)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ GtkTreePath *tree_path;
+ gint ret_val = 0;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return 0;
+
+ tree_view = GTK_TREE_VIEW (widget);
+
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ switch (gtk_tree_selection_get_mode (selection))
+ {
+ case GTK_SELECTION_SINGLE:
+ case GTK_SELECTION_BROWSE:
+ if (gtk_tree_selection_get_selected (selection, &tree_model, &iter))
+ {
+ gint row;
+
+ if (rows_selected)
+ {
+ *rows_selected = (gint *)g_malloc (sizeof(gint));
+ tree_path = gtk_tree_model_get_path (tree_model, &iter);
+ row = get_row_from_tree_path (tree_view, tree_path);
+ gtk_tree_path_free (tree_path);
+
+ /* shouldn't ever happen */
+ g_return_val_if_fail (row != -1, 0);
+
+ *rows_selected[0] = row;
+ }
+ ret_val = 1;
+ }
+ break;
+ case GTK_SELECTION_MULTIPLE:
+ {
+ GPtrArray *array = g_ptr_array_new();
+
+ gtk_tree_selection_selected_foreach (selection,
+ get_selected_rows,
+ array);
+ ret_val = array->len;
+
+ if (rows_selected && ret_val)
+ {
+ gint i;
+ *rows_selected = (gint *) g_malloc (ret_val * sizeof (gint));
+
+ for (i = 0; i < ret_val; i++)
+ {
+ gint row;
+
+ tree_path = (GtkTreePath *) g_ptr_array_index (array, i);
+ row = get_row_from_tree_path (tree_view, tree_path);
+ gtk_tree_path_free (tree_path);
+ (*rows_selected)[i] = row;
+ }
+ }
+ g_ptr_array_free (array, FALSE);
+ }
+ break;
+ case GTK_SELECTION_NONE:
+ break;
+ }
+ return ret_val;
+}
+
+static gboolean
+gail_tree_view_add_row_selection (AtkTable *table,
+ gint row)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+ GtkTreeSelection *selection;
+ GtkTreePath *tree_path;
+ GtkTreeIter iter_to_row;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ if (!gail_tree_view_is_row_selected (table, row))
+ {
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
+ {
+ tree_path = gtk_tree_path_new ();
+ gtk_tree_path_append_index (tree_path, row);
+ gtk_tree_selection_select_path (selection,tree_path);
+ gtk_tree_path_free (tree_path);
+ }
+ else
+ {
+ set_iter_nth_row (tree_view, &iter_to_row, row);
+ gtk_tree_selection_select_iter (selection, &iter_to_row);
+ }
+ }
+
+ return gail_tree_view_is_row_selected (table, row);
+}
+
+static gboolean
+gail_tree_view_remove_row_selection (AtkTable *table,
+ gint row)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeSelection *selection;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ tree_view = GTK_TREE_VIEW (widget);
+
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gail_tree_view_is_row_selected (table, row))
+ {
+ gtk_tree_selection_unselect_all (selection);
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+static AtkObject*
+gail_tree_view_get_row_header (AtkTable *table,
+ gint row)
+{
+ GailTreeViewRowInfo *row_info;
+
+ row_info = get_row_info (table, row);
+ if (row_info)
+ return row_info->header;
+ else
+ return NULL;
+}
+
+static void
+gail_tree_view_set_row_header (AtkTable *table,
+ gint row,
+ AtkObject *header)
+{
+ set_row_data (table, row, header, NULL, TRUE);
+}
+
+static AtkObject*
+gail_tree_view_get_column_header (AtkTable *table,
+ gint in_col)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *tv_col;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tv_col = get_column (tree_view, in_col);
+ return get_header_from_column (tv_col);
+}
+
+static void
+gail_tree_view_set_column_header (AtkTable *table,
+ gint in_col,
+ AtkObject *header)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *tv_col;
+ AtkPropertyValues values = { NULL };
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tv_col = get_column (tree_view, in_col);
+ if (tv_col == NULL)
+ return;
+
+ g_object_set_qdata_full (G_OBJECT (tv_col),
+ quark_column_header_object,
+ header,
+ g_object_unref);
+ if (header)
+ g_object_ref (header);
+ g_value_init (&values.new_value, G_TYPE_INT);
+ g_value_set_int (&values.new_value, in_col);
+
+ values.property_name = "accessible-table-column-header";
+ g_signal_emit_by_name (table,
+ "property_change::accessible-table-column-header",
+ &values, NULL);
+}
+
+static AtkObject*
+gail_tree_view_get_caption (AtkTable *table)
+{
+ GailTreeView* obj = GAIL_TREE_VIEW (table);
+
+ return obj->caption;
+}
+
+static void
+gail_tree_view_set_caption (AtkTable *table,
+ AtkObject *caption)
+{
+ GailTreeView* obj = GAIL_TREE_VIEW (table);
+ AtkPropertyValues values = { NULL };
+ AtkObject *old_caption;
+
+ old_caption = obj->caption;
+ obj->caption = caption;
+ if (obj->caption)
+ g_object_ref (obj->caption);
+ g_value_init (&values.old_value, G_TYPE_POINTER);
+ g_value_set_pointer (&values.old_value, old_caption);
+ g_value_init (&values.new_value, G_TYPE_POINTER);
+ g_value_set_pointer (&values.new_value, obj->caption);
+
+ values.property_name = "accessible-table-caption-object";
+ g_signal_emit_by_name (table,
+ "property_change::accessible-table-caption-object",
+ &values, NULL);
+ if (old_caption)
+ g_object_unref (old_caption);
+}
+
+static const gchar*
+gail_tree_view_get_column_description (AtkTable *table,
+ gint in_col)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *tv_col;
+ gchar *rc;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tv_col = get_column (tree_view, in_col);
+ if (tv_col == NULL)
+ return NULL;
+
+ rc = g_object_get_qdata (G_OBJECT (tv_col),
+ quark_column_desc_object);
+
+ if (rc != NULL)
+ return rc;
+ else
+ {
+ gchar *title_text;
+
+ g_object_get (tv_col, "title", &title_text, NULL);
+ return title_text;
+ }
+}
+
+static void
+gail_tree_view_set_column_description (AtkTable *table,
+ gint in_col,
+ const gchar *description)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *tv_col;
+ AtkPropertyValues values = { NULL };
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tv_col = get_column (tree_view, in_col);
+ if (tv_col == NULL)
+ return;
+
+ g_object_set_qdata_full (G_OBJECT (tv_col),
+ quark_column_desc_object,
+ g_strdup (description),
+ g_free);
+ g_value_init (&values.new_value, G_TYPE_INT);
+ g_value_set_int (&values.new_value, in_col);
+
+ values.property_name = "accessible-table-column-description";
+ g_signal_emit_by_name (table,
+ "property_change::accessible-table-column-description",
+ &values, NULL);
+}
+
+static const gchar*
+gail_tree_view_get_row_description (AtkTable *table,
+ gint row)
+{
+ GailTreeViewRowInfo *row_info;
+
+ row_info = get_row_info (table, row);
+ if (row_info)
+ return row_info->description;
+ else
+ return NULL;
+}
+
+static void
+gail_tree_view_set_row_description (AtkTable *table,
+ gint row,
+ const gchar *description)
+{
+ set_row_data (table, row, NULL, description, FALSE);
+}
+
+static AtkObject*
+gail_tree_view_get_summary (AtkTable *table)
+{
+ GailTreeView* obj = GAIL_TREE_VIEW (table);
+
+ return obj->summary;
+}
+
+static void
+gail_tree_view_set_summary (AtkTable *table,
+ AtkObject *accessible)
+{
+ GailTreeView* obj = GAIL_TREE_VIEW (table);
+ AtkPropertyValues values = { NULL };
+ AtkObject *old_summary;
+
+ old_summary = obj->summary;
+ obj->summary = accessible;
+ if (obj->summary)
+ g_object_ref (obj->summary);
+ g_value_init (&values.old_value, G_TYPE_POINTER);
+ g_value_set_pointer (&values.old_value, old_summary);
+ g_value_init (&values.new_value, G_TYPE_POINTER);
+ g_value_set_pointer (&values.new_value, obj->summary);
+
+ values.property_name = "accessible-table-summary";
+ g_signal_emit_by_name (table,
+ "property_change::accessible-table-ummary",
+ &values, NULL);
+ if (old_summary)
+ g_object_unref (old_summary);
+}
+
+static void
+set_row_data (AtkTable *table,
+ gint row,
+ AtkObject *header,
+ const gchar *description,
+ gboolean is_header)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+ GailTreeView* obj = GAIL_TREE_VIEW (table);
+ GailTreeViewRowInfo* row_info;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ GArray *array;
+ gboolean found = FALSE;
+ gint i;
+ AtkPropertyValues values = { NULL };
+ gchar *signal_name;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+
+ set_iter_nth_row (tree_view, &iter, row);
+ path = gtk_tree_model_get_path (tree_model, &iter);
+
+ if (obj->row_data == NULL)
+ obj->row_data = g_array_sized_new (FALSE, TRUE,
+ sizeof(GailTreeViewRowInfo *), 0);
+
+ array = obj->row_data;
+
+ for (i = 0; i < array->len; i++)
+ {
+ GtkTreePath *row_path;
+
+ row_info = g_array_index (array, GailTreeViewRowInfo*, i);
+ row_path = gtk_tree_row_reference_get_path (row_info->row_ref);
+
+ if (row_path != NULL)
+ {
+ if (path && gtk_tree_path_compare (row_path, path) == 0)
+ found = TRUE;
+
+ gtk_tree_path_free (row_path);
+
+ if (found)
+ {
+ if (is_header)
+ {
+ if (row_info->header)
+ g_object_unref (row_info->header);
+ row_info->header = header;
+ if (row_info->header)
+ g_object_ref (row_info->header);
+ }
+ else
+ {
+ g_free (row_info->description);
+ row_info->description = g_strdup (description);
+ }
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ /* if not found */
+ row_info = g_malloc (sizeof(GailTreeViewRowInfo));
+ row_info->row_ref = gtk_tree_row_reference_new (tree_model, path);
+ if (is_header)
+ {
+ row_info->header = header;
+ if (row_info->header)
+ g_object_ref (row_info->header);
+ row_info->description = NULL;
+ }
+ else
+ {
+ row_info->header = NULL;
+ row_info->description = g_strdup (description);
+ }
+ g_array_append_val (array, row_info);
+ }
+ g_value_init (&values.new_value, G_TYPE_INT);
+ g_value_set_int (&values.new_value, row);
+
+ if (is_header)
+ {
+ values.property_name = "accessible-table-row-header";
+ signal_name = "property_change::accessible-table-row-header";
+ }
+ else
+ {
+ values.property_name = "accessible-table-row-description";
+ signal_name = "property-change::accessible-table-row-description";
+ }
+ g_signal_emit_by_name (table,
+ signal_name,
+ &values, NULL);
+
+ gtk_tree_path_free (path);
+}
+
+
+static GailTreeViewRowInfo*
+get_row_info (AtkTable *table,
+ gint row)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+ GailTreeView* obj = GAIL_TREE_VIEW (table);
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ GArray *array;
+ GailTreeViewRowInfo *rc = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
+ if (widget == NULL)
+ /* State is defunct */
+ return NULL;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+
+ set_iter_nth_row (tree_view, &iter, row);
+ path = gtk_tree_model_get_path (tree_model, &iter);
+ array = obj->row_data;
+
+ if (array != NULL)
+ {
+ GailTreeViewRowInfo *row_info;
+ GtkTreePath *row_path;
+ gint i;
+
+ for (i = 0; i < array->len; i++)
+ {
+ row_info = g_array_index (array, GailTreeViewRowInfo*, i);
+ row_path = gtk_tree_row_reference_get_path (row_info->row_ref);
+ if (row_path != NULL)
+ {
+ if (path && gtk_tree_path_compare (row_path, path) == 0)
+ rc = row_info;
+
+ gtk_tree_path_free (row_path);
+
+ if (rc != NULL)
+ break;
+ }
+ }
+ }
+
+ gtk_tree_path_free (path);
+ return rc;
+}
+/* atkselection.h */
+
+static void atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ iface->add_selection = gail_tree_view_add_selection;
+ iface->clear_selection = gail_tree_view_clear_selection;
+ iface->ref_selection = gail_tree_view_ref_selection;
+ iface->get_selection_count = gail_tree_view_get_selection_count;
+ iface->is_child_selected = gail_tree_view_is_child_selected;
+}
+
+static gboolean
+gail_tree_view_add_selection (AtkSelection *selection,
+ gint i)
+{
+ AtkTable *table;
+ gint n_columns;
+ gint row;
+
+ table = ATK_TABLE (selection);
+ n_columns = gail_tree_view_get_n_columns (table);
+ if (n_columns != 1)
+ return FALSE;
+
+ row = gail_tree_view_get_row_at_index (table, i);
+ return gail_tree_view_add_row_selection (table, row);
+}
+
+static gboolean
+gail_tree_view_clear_selection (AtkSelection *selection)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeSelection *tree_selection;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ tree_view = GTK_TREE_VIEW (widget);
+
+ tree_selection = gtk_tree_view_get_selection (tree_view);
+ gtk_tree_selection_unselect_all (tree_selection);
+
+ return TRUE;
+}
+
+static AtkObject*
+gail_tree_view_ref_selection (AtkSelection *selection,
+ gint i)
+{
+ AtkTable *table;
+ gint row;
+ gint n_selected;
+ gint n_columns;
+ gint *selected;
+
+ table = ATK_TABLE (selection);
+ n_columns = gail_tree_view_get_n_columns (table);
+ n_selected = gail_tree_view_get_selected_rows (table, &selected);
+ if (i >= n_columns * n_selected)
+ return NULL;
+
+ row = selected[i / n_columns];
+ g_free (selected);
+
+ return gail_tree_view_table_ref_at (table, row, i % n_columns);
+}
+
+static gint
+gail_tree_view_get_selection_count (AtkSelection *selection)
+{
+ AtkTable *table;
+ gint n_selected;
+
+ table = ATK_TABLE (selection);
+ n_selected = gail_tree_view_get_selected_rows (table, NULL);
+ if (n_selected > 0)
+ n_selected *= gail_tree_view_get_n_columns (table);
+ return n_selected;
+}
+
+static gboolean
+gail_tree_view_is_child_selected (AtkSelection *selection,
+ gint i)
+{
+ GtkWidget *widget;
+ gint row;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ row = atk_table_get_row_at_index (ATK_TABLE (selection), i);
+
+ return gail_tree_view_is_row_selected (ATK_TABLE (selection), row);
+}
+
+
+static void gail_cell_parent_interface_init (GailCellParentIface *iface)
+{
+ iface->get_cell_extents = gail_tree_view_get_cell_extents;
+ iface->get_cell_area = gail_tree_view_get_cell_area;
+ iface->grab_focus = gail_tree_view_grab_cell_focus;
+}
+
+static void
+gail_tree_view_get_cell_extents (GailCellParent *parent,
+ GailCell *cell,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GdkWindow *bin_window;
+ GdkRectangle cell_rect;
+ gint w_x, w_y;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ gail_tree_view_get_cell_area (parent, cell, &cell_rect);
+ bin_window = gtk_tree_view_get_bin_window (tree_view);
+ gdk_window_get_origin (bin_window, &w_x, &w_y);
+
+ if (coord_type == ATK_XY_WINDOW)
+ {
+ GdkWindow *window;
+ gint x_toplevel, y_toplevel;
+
+ window = gdk_window_get_toplevel (bin_window);
+ gdk_window_get_origin (window, &x_toplevel, &y_toplevel);
+
+ w_x -= x_toplevel;
+ w_y -= y_toplevel;
+ }
+
+ *width = cell_rect.width;
+ *height = cell_rect.height;
+ if (is_cell_showing (tree_view, &cell_rect))
+ {
+ *x = cell_rect.x + w_x;
+ *y = cell_rect.y + w_y;
+ }
+ else
+ {
+ *x = G_MININT;
+ *y = G_MININT;
+ }
+}
+
+#define EXTRA_EXPANDER_PADDING 4
+
+static void
+gail_tree_view_get_cell_area (GailCellParent *parent,
+ GailCell *cell,
+ GdkRectangle *cell_rect)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *tv_col;
+ GtkTreePath *path;
+ AtkObject *parent_cell;
+ GailTreeViewCellInfo *cell_info;
+ GailCell *top_cell;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
+ if (widget == NULL)
+ /* State is defunct */
+ return;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ parent_cell = atk_object_get_parent (ATK_OBJECT (cell));
+ if (parent_cell != ATK_OBJECT (parent))
+ {
+ /*
+ * GailCell is in a GailContainerCell
+ */
+ top_cell = GAIL_CELL (parent_cell);
+ }
+ else
+ {
+ top_cell = cell;
+ }
+ cell_info = find_cell_info (GAIL_TREE_VIEW (parent), top_cell, NULL, TRUE);
+ gail_return_if_fail (cell_info);
+ gail_return_if_fail (cell_info->cell_col_ref);
+ gail_return_if_fail (cell_info->cell_row_ref);
+ path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ tv_col = cell_info->cell_col_ref;
+ if (path && cell_info->in_use)
+ {
+ GtkTreeViewColumn *expander_column;
+ gint focus_line_width;
+
+ gtk_tree_view_get_cell_area (tree_view, path, tv_col, cell_rect);
+ expander_column = gtk_tree_view_get_expander_column (tree_view);
+ if (expander_column == tv_col)
+ {
+ gint expander_size;
+
+ gtk_widget_style_get (widget,
+ "expander_size", &expander_size,
+ NULL);
+
+ cell_rect->x += expander_size + EXTRA_EXPANDER_PADDING;
+ cell_rect->width -= expander_size + EXTRA_EXPANDER_PADDING;
+ }
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_line_width,
+ NULL);
+
+ cell_rect->x += focus_line_width;
+ cell_rect->width -= 2 * focus_line_width;
+
+ gtk_tree_path_free (path);
+
+ /*
+ * A column has more than one renderer so we find the position and width
+ * of each.
+ */
+ if (top_cell != cell)
+ {
+ gint cell_index;
+ gboolean found;
+ gint cell_start;
+ gint cell_width;
+ GList *renderers;
+ GtkCellRenderer *renderer;
+
+ cell_index = atk_object_get_index_in_parent (ATK_OBJECT (cell));
+ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tv_col));
+ renderer = g_list_nth_data (renderers, cell_index);
+
+ found = gtk_tree_view_column_cell_get_position (tv_col, renderer, &cell_start, &cell_width);
+ if (found)
+ {
+ cell_rect->x += cell_start;
+ cell_rect->width = cell_width;
+ }
+ g_list_free (renderers);
+ }
+
+ }
+}
+
+static gboolean
+gail_tree_view_grab_cell_focus (GailCellParent *parent,
+ GailCell *cell)
+{
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *tv_col;
+ GtkTreePath *path;
+ AtkObject *parent_cell;
+ AtkObject *cell_object;
+ GailTreeViewCellInfo *cell_info;
+ GtkCellRenderer *renderer = NULL;
+ GtkWidget *toplevel;
+ gint index;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
+ if (widget == NULL)
+ /* State is defunct */
+ return FALSE;
+
+ tree_view = GTK_TREE_VIEW (widget);
+
+ cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
+ gail_return_val_if_fail (cell_info, FALSE);
+ gail_return_val_if_fail (cell_info->cell_col_ref, FALSE);
+ gail_return_val_if_fail (cell_info->cell_row_ref, FALSE);
+ cell_object = ATK_OBJECT (cell);
+ parent_cell = atk_object_get_parent (cell_object);
+ tv_col = cell_info->cell_col_ref;
+ if (parent_cell != ATK_OBJECT (parent))
+ {
+ /*
+ * GailCell is in a GailContainerCell.
+ * The GtkTreeViewColumn has multiple renderers;
+ * find the corresponding one.
+ */
+ GList *renderers;
+
+ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tv_col));
+ if (cell_info->in_use) {
+ index = atk_object_get_index_in_parent (cell_object);
+ renderer = g_list_nth_data (renderers, index);
+ }
+ g_list_free (renderers);
+ }
+ path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ if (path && cell_info->in_use)
+ {
+ if (renderer)
+ gtk_tree_view_set_cursor_on_cell (tree_view, path, tv_col, renderer, FALSE);
+ else
+ gtk_tree_view_set_cursor (tree_view, path, tv_col, FALSE);
+
+ gtk_tree_path_free (path);
+ gtk_widget_grab_focus (widget);
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (gtk_widget_is_toplevel (toplevel))
+ {
+#ifdef GDK_WINDOWING_X11
+ gtk_window_present_with_time (GTK_WINDOW (toplevel),
+ gdk_x11_get_server_time (gtk_widget_get_window (widget)));
+#else
+ gtk_window_present (GTK_WINDOW (toplevel));
+#endif
+ }
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/* signal handling */
+
+static gboolean
+gail_tree_view_expand_row_gtk (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ AtkObject *atk_obj;
+ GailTreeView *gailview;
+
+ g_assert (GTK_IS_TREE_VIEW (tree_view));
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
+
+ g_assert (GAIL_IS_TREE_VIEW (atk_obj));
+
+ gailview = GAIL_TREE_VIEW (atk_obj);
+
+ /*
+ * The visible rectangle has not been updated when this signal is emitted
+ * so we process the signal when the GTK processing is completed
+ */
+ /* this seems wrong since it overwrites any other pending expand handlers... */
+ gailview->idle_expand_path = gtk_tree_path_copy (path);
+ if (gailview->idle_expand_id)
+ g_source_remove (gailview->idle_expand_id);
+ gailview->idle_expand_id = gdk_threads_add_idle (idle_expand_row, gailview);
+ return FALSE;
+}
+
+static gint
+idle_expand_row (gpointer data)
+{
+ GailTreeView *gailview = data;
+ GtkTreePath *path;
+ GtkTreeView *tree_view;
+ GtkTreeIter iter;
+ GtkTreeModel *tree_model;
+ gint n_inserted, row;
+
+ gailview->idle_expand_id = 0;
+
+ path = gailview->idle_expand_path;
+ tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (gailview)));
+
+ g_assert (GTK_IS_TREE_VIEW (tree_view));
+
+ tree_model = gtk_tree_view_get_model(tree_view);
+ if (!tree_model)
+ return FALSE;
+
+ if (!path || !gtk_tree_model_get_iter (tree_model, &iter, path))
+ return FALSE;
+
+ /*
+ * Update visibility of cells below expansion row
+ */
+ traverse_cells (gailview, path, FALSE, FALSE);
+ /*
+ * Figure out number of visible children, the following test
+ * should not fail
+ */
+ if (gtk_tree_model_iter_has_child (tree_model, &iter))
+ {
+ GtkTreePath *path_copy;
+
+ /*
+ * By passing path into this function, we find the number of
+ * visible children of path.
+ */
+ path_copy = gtk_tree_path_copy (path);
+ gtk_tree_path_append_index(path_copy, 0);
+
+ n_inserted = 0;
+ iterate_thru_children (tree_view, tree_model,
+ path_copy, NULL, &n_inserted, 0);
+ gtk_tree_path_free (path_copy);
+ }
+ else
+ {
+ /* We can get here if the row expanded callback deleted the row */
+ return FALSE;
+ }
+
+ /* Set expand state */
+ set_expand_state (tree_view, tree_model, gailview, path, TRUE);
+
+ row = get_row_from_tree_path (tree_view, path);
+
+ /* shouldn't ever happen */
+ if (row == -1)
+ g_assert_not_reached ();
+
+ /* Must add 1 because the "added rows" are below the row being expanded */
+ row += 1;
+
+ g_signal_emit_by_name (gailview, "row_inserted", row, n_inserted);
+
+ gailview->idle_expand_path = NULL;
+
+ gtk_tree_path_free (path);
+
+ return FALSE;
+}
+
+static gboolean
+gail_tree_view_collapse_row_gtk (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ GtkTreeModel *tree_model;
+ AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
+ GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
+ gint row;
+
+ tree_model = gtk_tree_view_get_model (tree_view);
+
+ clean_rows (gailview);
+
+ /*
+ * Update visibility of cells below collapsed row
+ */
+ traverse_cells (gailview, path, FALSE, FALSE);
+ /* Set collapse state */
+ set_expand_state (tree_view, tree_model, gailview, path, FALSE);
+
+ gail_return_val_if_fail (gailview->n_children_deleted, FALSE);
+ row = get_row_from_tree_path (tree_view, path);
+ gail_return_val_if_fail (row != -1, FALSE);
+ g_signal_emit_by_name (atk_obj, "row_deleted", row,
+ gailview->n_children_deleted);
+ gailview->n_children_deleted = 0;
+ return FALSE;
+}
+
+static void
+gail_tree_view_size_allocate_gtk (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ AtkObject *atk_obj = gtk_widget_get_accessible (widget);
+ GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
+
+ /*
+ * If the size allocation changes, the visibility of cells may change so
+ * update the cells visibility.
+ */
+ traverse_cells (gailview, NULL, FALSE, FALSE);
+}
+
+static void
+gail_tree_view_changed_gtk (GtkTreeSelection *selection,
+ gpointer data)
+{
+ GailTreeView *gailview;
+ GtkTreeView *tree_view;
+ GtkWidget *widget;
+ GList *cell_list;
+ GList *l;
+ GailTreeViewCellInfo *info;
+ GtkTreeSelection *tree_selection;
+ GtkTreePath *path;
+
+ gailview = GAIL_TREE_VIEW (data);
+ cell_list = gailview->cell_data;
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gailview));
+ if (widget == NULL)
+ /*
+ * destroy signal emitted for widget
+ */
+ return;
+ tree_view = GTK_TREE_VIEW (widget);
+
+ tree_selection = gtk_tree_view_get_selection (tree_view);
+
+ clean_rows (gailview);
+
+ for (l = cell_list; l; l = l->next)
+ {
+ info = (GailTreeViewCellInfo *) (l->data);
+
+ if (info->in_use)
+ {
+ gail_cell_remove_state (info->cell, ATK_STATE_SELECTED, TRUE);
+
+ path = gtk_tree_row_reference_get_path (info->cell_row_ref);
+ if (path && gtk_tree_selection_path_is_selected (tree_selection, path))
+ gail_cell_add_state (info->cell, ATK_STATE_SELECTED, TRUE);
+ gtk_tree_path_free (path);
+ }
+ }
+ if (gtk_widget_get_realized (widget))
+ g_signal_emit_by_name (gailview, "selection_changed");
+}
+
+static void
+columns_changed (GtkTreeView *tree_view)
+{
+ AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET(tree_view));
+ GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
+ GList *tv_cols, *tmp_list;
+ gboolean column_found;
+ gboolean move_found = FALSE;
+ gboolean stale_set = FALSE;
+ gint column_count = 0;
+ gint i;
+
+ /*
+ * This function must determine if the change is an add, delete or
+ * a move based upon its cache of TreeViewColumns in
+ * gailview->col_data
+ */
+ tv_cols = gtk_tree_view_get_columns (tree_view);
+
+ /* check for adds or moves */
+ for (tmp_list = tv_cols; tmp_list; tmp_list = tmp_list->next)
+ {
+ column_found = FALSE;
+
+ for (i = 0; i < gailview->col_data->len; i++)
+ {
+
+ if ((GtkTreeViewColumn *)tmp_list->data ==
+ (GtkTreeViewColumn *)g_array_index (gailview->col_data,
+ GtkTreeViewColumn *, i))
+ {
+ column_found = TRUE;
+
+ /* If the column isn't in the same position, a move happened */
+ if (!move_found && i != column_count)
+ {
+ if (!stale_set)
+ {
+ /* Set all rows to ATK_STATE_STALE */
+ traverse_cells (gailview, NULL, TRUE, FALSE);
+ stale_set = TRUE;
+ }
+
+ /* Just emit one column reordered signal when a move happens */
+ g_signal_emit_by_name (atk_obj, "column_reordered");
+ move_found = TRUE;
+ }
+
+ break;
+ }
+ }
+
+ /*
+ * If column_found is FALSE, then an insert happened for column
+ * number column_count
+ */
+ if (!column_found)
+ {
+ gint n_cols, n_rows, row;
+
+ if (!stale_set)
+ {
+ /* Set all rows to ATK_STATE_STALE */
+ traverse_cells (gailview, NULL, TRUE, FALSE);
+ stale_set = TRUE;
+ }
+
+ /* Generate column-inserted signal */
+ g_signal_emit_by_name (atk_obj, "column_inserted", column_count, 1);
+
+ /* Generate children-changed signals */
+ n_rows = get_row_count (gtk_tree_view_get_model (tree_view));
+ n_cols = get_n_actual_columns (tree_view);
+ for (row = 0; row < n_rows; row++)
+ {
+ /*
+ * Pass NULL as the child object, i.e. 4th argument.
+ */
+ g_signal_emit_by_name (atk_obj, "children_changed::add",
+ ((row * n_cols) + column_count), NULL, NULL);
+ }
+ }
+
+ column_count++;
+ }
+
+ /* check for deletes */
+ for (i = 0; i < gailview->col_data->len; i++)
+ {
+ column_found = FALSE;
+
+ for (tmp_list = tv_cols; tmp_list; tmp_list = tmp_list->next)
+ {
+ if ((GtkTreeViewColumn *)tmp_list->data ==
+ (GtkTreeViewColumn *)g_array_index (gailview->col_data,
+ GtkTreeViewColumn *, i))
+ {
+ column_found = TRUE;
+ break;
+ }
+ }
+
+ /*
+ * If column_found is FALSE, then a delete happened for column
+ * number i
+ */
+ if (!column_found)
+ {
+ gint n_rows, n_cols, row;
+
+ clean_cols (gailview,
+ (GtkTreeViewColumn *)g_array_index (gailview->col_data,
+ GtkTreeViewColumn *, i));
+
+ if (!stale_set)
+ {
+ /* Set all rows to ATK_STATE_STALE */
+ traverse_cells (gailview, NULL, TRUE, FALSE);
+ stale_set = TRUE;
+ }
+
+ /* Generate column-deleted signal */
+ g_signal_emit_by_name (atk_obj, "column_deleted", i, 1);
+
+ /* Generate children-changed signals */
+ n_rows = get_row_count (gtk_tree_view_get_model (tree_view));
+ n_cols = get_n_actual_columns (tree_view);
+ for (row = 0; row < n_rows; row++)
+ {
+ /*
+ * Pass NULL as the child object, 4th argument.
+ */
+ g_signal_emit_by_name (atk_obj, "children_changed::remove",
+ ((row * n_cols) + column_count), NULL, NULL);
+ }
+ }
+ }
+
+ /* rebuild the array */
+
+ g_array_free (gailview->col_data, TRUE);
+ gailview->col_data = g_array_sized_new (FALSE, TRUE,
+ sizeof(GtkTreeViewColumn *), 0);
+
+ for (tmp_list = tv_cols; tmp_list; tmp_list = tmp_list->next)
+ g_array_append_val (gailview->col_data, tmp_list->data);
+ g_list_free (tv_cols);
+}
+
+static void
+cursor_changed (GtkTreeView *tree_view)
+{
+ GailTreeView *gailview;
+
+ gailview = GAIL_TREE_VIEW (gtk_widget_get_accessible (GTK_WIDGET (tree_view)));
+ if (gailview->idle_cursor_changed_id != 0)
+ return;
+
+ /*
+ * We notify the focus change in a idle handler so that the processing
+ * of the cursor change is completed when the focus handler is called.
+ * This will allow actions to be called in the focus handler
+ */
+ gailview->idle_cursor_changed_id = gdk_threads_add_idle (idle_cursor_changed, gailview);
+}
+
+static gint
+idle_cursor_changed (gpointer data)
+{
+ GailTreeView *gail_tree_view = GAIL_TREE_VIEW (data);
+ GtkTreeView *tree_view;
+ GtkWidget *widget;
+ AtkObject *cell;
+
+ gail_tree_view->idle_cursor_changed_id = 0;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gail_tree_view));
+ /*
+ * Widget has been deleted
+ */
+ if (widget == NULL)
+ return FALSE;
+
+ tree_view = GTK_TREE_VIEW (widget);
+
+ cell = gail_tree_view_ref_focus_cell (tree_view);
+ if (cell)
+ {
+ if (cell != gail_tree_view->focus_cell)
+ {
+ if (gail_tree_view->focus_cell)
+ {
+ gail_cell_remove_state (GAIL_CELL (gail_tree_view->focus_cell), ATK_STATE_ACTIVE, FALSE);
+ gail_cell_remove_state (GAIL_CELL (gail_tree_view->focus_cell), ATK_STATE_FOCUSED, FALSE);
+ g_object_unref (gail_tree_view->focus_cell);
+ }
+ gail_tree_view->focus_cell = cell;
+
+ if (gtk_widget_has_focus (widget))
+ {
+ gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_ACTIVE, FALSE);
+ gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_FOCUSED, FALSE);
+ }
+ g_signal_emit_by_name (gail_tree_view,
+ "active-descendant-changed",
+ cell);
+ }
+ else
+ g_object_unref (cell);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+focus_in (GtkWidget *widget)
+{
+ GtkTreeView *tree_view;
+ GailTreeView *gail_tree_view;
+ AtkStateSet *state_set;
+ AtkObject *cell;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ gail_tree_view = GAIL_TREE_VIEW (gtk_widget_get_accessible (widget));
+
+ if (gail_tree_view->focus_cell == NULL)
+ {
+ cell = gail_tree_view_ref_focus_cell (tree_view);
+ if (cell)
+ {
+ state_set = atk_object_ref_state_set (cell);
+ if (state_set)
+ {
+ if (!atk_state_set_contains_state (state_set, ATK_STATE_FOCUSED))
+ {
+ gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_ACTIVE, FALSE);
+ gail_tree_view->focus_cell = cell;
+ gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_FOCUSED, FALSE);
+ g_signal_emit_by_name (gail_tree_view,
+ "active-descendant-changed",
+ cell);
+ }
+ g_object_unref (state_set);
+ }
+ }
+ }
+ return FALSE;
+}
+
+static gboolean
+focus_out (GtkWidget *widget)
+{
+ GailTreeView *gail_tree_view;
+
+ gail_tree_view = GAIL_TREE_VIEW (gtk_widget_get_accessible (widget));
+ if (gail_tree_view->focus_cell)
+ {
+ gail_cell_remove_state (GAIL_CELL (gail_tree_view->focus_cell), ATK_STATE_ACTIVE, FALSE);
+ gail_cell_remove_state (GAIL_CELL (gail_tree_view->focus_cell), ATK_STATE_FOCUSED, FALSE);
+ g_object_unref (gail_tree_view->focus_cell);
+ gail_tree_view->focus_cell = NULL;
+ }
+ return FALSE;
+}
+
+static void
+model_row_changed (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ GtkTreeView *tree_view = GTK_TREE_VIEW(user_data);
+ GailTreeView *gailview;
+ GtkTreePath *cell_path;
+ GList *l;
+ GailTreeViewCellInfo *cell_info;
+
+ gailview = GAIL_TREE_VIEW (gtk_widget_get_accessible (GTK_WIDGET (tree_view)));
+
+ /* Loop through our cached cells */
+ /* Must loop through them all */
+ for (l = gailview->cell_data; l; l = l->next)
+ {
+ cell_info = (GailTreeViewCellInfo *) l->data;
+ if (cell_info->in_use)
+ {
+ cell_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+
+ if (cell_path != NULL)
+ {
+ if (path && gtk_tree_path_compare (cell_path, path) == 0)
+ {
+ if (GAIL_IS_RENDERER_CELL (cell_info->cell))
+ {
+ update_cell_value (GAIL_RENDERER_CELL (cell_info->cell),
+ gailview, TRUE);
+ }
+ }
+ gtk_tree_path_free (cell_path);
+ }
+ }
+ }
+ g_signal_emit_by_name (gailview, "visible-data-changed");
+}
+
+static void
+column_visibility_changed (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ if (strcmp (pspec->name, "visible") == 0)
+ {
+ /*
+ * A column has been made visible or invisible
+ *
+ * We update our cache of cells and emit model_changed signal
+ */
+ GtkTreeView *tree_view = (GtkTreeView *)user_data;
+ GailTreeView *gailview;
+ GList *l;
+ GailTreeViewCellInfo *cell_info;
+ GtkTreeViewColumn *this_col = GTK_TREE_VIEW_COLUMN (object);
+ GtkTreeViewColumn *tv_col;
+
+ gailview = GAIL_TREE_VIEW (gtk_widget_get_accessible (GTK_WIDGET (tree_view))
+);
+ g_signal_emit_by_name (gailview, "model_changed");
+
+ for (l = gailview->cell_data; l; l = l->next)
+ {
+ cell_info = (GailTreeViewCellInfo *) l->data;
+ if (cell_info->in_use)
+ {
+ tv_col = cell_info->cell_col_ref;
+ if (tv_col == this_col)
+ {
+ GtkTreePath *row_path;
+ row_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ if (GAIL_IS_RENDERER_CELL (cell_info->cell))
+ {
+ if (gtk_tree_view_column_get_visible (tv_col))
+ set_cell_visibility (tree_view,
+ cell_info->cell,
+ tv_col, row_path, FALSE);
+ else
+ {
+ gail_cell_remove_state (cell_info->cell,
+ ATK_STATE_VISIBLE, TRUE);
+ gail_cell_remove_state (cell_info->cell,
+ ATK_STATE_SHOWING, TRUE);
+ }
+ }
+ gtk_tree_path_free (row_path);
+ }
+ }
+ }
+ }
+}
+
+static void
+model_row_inserted (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ GtkTreeView *tree_view = (GtkTreeView *)user_data;
+ GtkTreePath *path_copy;
+ AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
+ GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
+ gint row, n_inserted, child_row;
+
+ if (gailview->idle_expand_id)
+ {
+ g_source_remove (gailview->idle_expand_id);
+ gailview->idle_expand_id = 0;
+
+ /* don't do this if the insertion precedes the idle path, since it will now be invalid */
+ if (path && gailview->idle_expand_path &&
+ (gtk_tree_path_compare (path, gailview->idle_expand_path) > 0))
+ set_expand_state (tree_view, tree_model, gailview, gailview->idle_expand_path, FALSE);
+ if (gailview->idle_expand_path)
+ gtk_tree_path_free (gailview->idle_expand_path);
+ }
+ /* Check to see if row is visible */
+ row = get_row_from_tree_path (tree_view, path);
+
+ /*
+ * A row insert is not necessarily visible. For example,
+ * a row can be draged & dropped into another row, which
+ * causes an insert on the model that isn't visible in the
+ * view. Only generate a signal if the inserted row is
+ * visible.
+ */
+ if (row != -1)
+ {
+ GtkTreeIter iter;
+ gint n_cols, col;
+
+ gtk_tree_model_get_iter (tree_model, &iter, path);
+
+ /* Figure out number of visible children. */
+ if (gtk_tree_model_iter_has_child (tree_model, &iter))
+ {
+ /*
+ * By passing path into this function, we find the number of
+ * visible children of path.
+ */
+ n_inserted = 0;
+ iterate_thru_children (tree_view, tree_model,
+ path, NULL, &n_inserted, 0);
+
+ /* Must add one to include the row that is being added */
+ n_inserted++;
+ }
+ else
+ n_inserted = 1;
+
+ /* Set rows below the inserted row to ATK_STATE_STALE */
+ traverse_cells (gailview, path, TRUE, TRUE);
+
+ /* Generate row-inserted signal */
+ g_signal_emit_by_name (atk_obj, "row_inserted", row, n_inserted);
+
+ /* Generate children-changed signals */
+ n_cols = gail_tree_view_get_n_columns (ATK_TABLE (atk_obj));
+ for (child_row = row; child_row < (row + n_inserted); child_row++)
+ {
+ for (col = 0; col < n_cols; col++)
+ {
+ /*
+ * Pass NULL as the child object, i.e. 4th argument
+ */
+ g_signal_emit_by_name (atk_obj, "children_changed::add",
+ ((row * n_cols) + col), NULL, NULL);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * The row has been inserted inside another row. This can
+ * cause a row that previously couldn't be expanded to now
+ * be expandable.
+ */
+ path_copy = gtk_tree_path_copy (path);
+ gtk_tree_path_up (path_copy);
+ set_expand_state (tree_view, tree_model, gailview, path_copy, TRUE);
+ gtk_tree_path_free (path_copy);
+ }
+}
+
+static void
+model_row_deleted (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ gpointer user_data)
+{
+ GtkTreeView *tree_view;
+ GtkTreePath *path_copy;
+ AtkObject *atk_obj;
+ GailTreeView *gailview;
+ gint row, col, n_cols;
+
+ tree_view = (GtkTreeView *)user_data;
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
+ gailview = GAIL_TREE_VIEW (atk_obj);
+
+ if (gailview->idle_expand_id)
+ {
+ g_source_remove (gailview->idle_expand_id);
+ gtk_tree_path_free (gailview->idle_expand_path);
+ gailview->idle_expand_id = 0;
+ }
+ /* Check to see if row is visible */
+ clean_rows (gailview);
+
+ /* Set rows at or below the specified row to ATK_STATE_STALE */
+ traverse_cells (gailview, path, TRUE, TRUE);
+
+ /*
+ * If deleting a row with a depth > 1, then this may affect the
+ * expansion/contraction of its parent(s). Make sure this is
+ * handled.
+ */
+ if (gtk_tree_path_get_depth (path) > 1)
+ {
+ path_copy = gtk_tree_path_copy (path);
+ gtk_tree_path_up (path_copy);
+ set_expand_state (tree_view, tree_model, gailview, path_copy, TRUE);
+ gtk_tree_path_free (path_copy);
+ }
+ row = get_row_from_tree_path (tree_view, path);
+ /*
+ * If the row which is deleted is not visible because it is a child of
+ * a collapsed row then row will be -1
+ */
+ if (row > 0)
+ g_signal_emit_by_name (atk_obj, "row_deleted", row,
+ gailview->n_children_deleted + 1);
+ gailview->n_children_deleted = 0;
+
+ /* Generate children-changed signals */
+ n_cols = get_n_actual_columns (tree_view);
+ for (col = 0; col < n_cols; col++)
+ {
+ /*
+ * Pass NULL as the child object, 4th argument.
+ */
+ g_signal_emit_by_name (atk_obj, "children_changed::remove",
+ ((row * n_cols) + col), NULL, NULL);
+ }
+}
+
+/*
+ * This function gets called when a row is deleted or when rows are
+ * removed from the view due to a collapse event. Note that the
+ * count is the number of visible *children* of the deleted row,
+ * so it does not include the row being deleted.
+ *
+ * As this function is called before the rows are removed we just note the
+ * number of rows and then deal with it when we get a notification that
+ * rows were deleted or collapsed.
+ */
+static void
+destroy_count_func (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ gint count,
+ gpointer user_data)
+{
+ AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
+ GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
+
+ gail_return_if_fail (gailview->n_children_deleted == 0);
+ gailview->n_children_deleted = count;
+}
+
+static void
+model_rows_reordered (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gint *new_order,
+ gpointer user_data)
+{
+ GtkTreeView *tree_view = (GtkTreeView *)user_data;
+ AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
+ GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
+
+ if (gailview->idle_expand_id)
+ {
+ g_source_remove (gailview->idle_expand_id);
+ gtk_tree_path_free (gailview->idle_expand_path);
+ gailview->idle_expand_id = 0;
+ }
+ traverse_cells (gailview, NULL, TRUE, FALSE);
+
+ g_signal_emit_by_name (atk_obj, "row_reordered");
+}
+
+static void
+adjustment_changed (GtkAdjustment *adjustment,
+ GtkTreeView *tree_view)
+{
+ AtkObject *atk_obj;
+ GailTreeView* obj;
+
+ /*
+ * The scrollbars have changed
+ */
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
+ obj = GAIL_TREE_VIEW (atk_obj);
+
+ traverse_cells (obj, NULL, FALSE, FALSE);
+}
+
+static void
+set_cell_visibility (GtkTreeView *tree_view,
+ GailCell *cell,
+ GtkTreeViewColumn *tv_col,
+ GtkTreePath *tree_path,
+ gboolean emit_signal)
+{
+ GdkRectangle cell_rect;
+
+ /* Get these three values in tree coords */
+ if (gtk_widget_get_realized (GTK_WIDGET (tree_view)))
+ gtk_tree_view_get_cell_area (tree_view, tree_path, tv_col, &cell_rect);
+ else
+ cell_rect.height = 0;
+
+ if (cell_rect.height > 0)
+ {
+ /*
+ * The height will be zero for a cell for which an antecedent is not
+ * expanded
+ */
+ gail_cell_add_state (cell, ATK_STATE_VISIBLE, emit_signal);
+ if (is_cell_showing (tree_view, &cell_rect))
+ gail_cell_add_state (cell, ATK_STATE_SHOWING, emit_signal);
+ else
+ gail_cell_remove_state (cell, ATK_STATE_SHOWING, emit_signal);
+ }
+ else
+ {
+ gail_cell_remove_state (cell, ATK_STATE_VISIBLE, emit_signal);
+ gail_cell_remove_state (cell, ATK_STATE_SHOWING, emit_signal);
+ }
+}
+
+static gboolean
+is_cell_showing (GtkTreeView *tree_view,
+ GdkRectangle *cell_rect)
+{
+ GdkRectangle rect, *visible_rect;
+ GdkRectangle rect1, *tree_cell_rect;
+ gint bx, by;
+ gboolean is_showing;
+ /*
+ * A cell is considered "SHOWING" if any part of the cell is in the visible
+ * area. Other ways we could do this is by a cell's midpoint or if the cell
+ * is fully in the visible range. Since we have the cell_rect x,y,width,height
+ * of the cell, any of these is easy to compute.
+ *
+ * It is assumed that cell's rectangle is in widget coordinates so we
+ * must transform to tree cordinates.
+ */
+ visible_rect = ▭
+ tree_cell_rect = &rect1;
+ tree_cell_rect->x = cell_rect->x;
+ tree_cell_rect->y = cell_rect->y;
+ tree_cell_rect->width = cell_rect->width;
+ tree_cell_rect->height = cell_rect->height;
+
+ gtk_tree_view_get_visible_rect (tree_view, visible_rect);
+ gtk_tree_view_convert_tree_to_bin_window_coords (tree_view, visible_rect->x,
+ visible_rect->y, &bx, &by);
+
+ if (((tree_cell_rect->x + tree_cell_rect->width) < bx) ||
+ ((tree_cell_rect->y + tree_cell_rect->height) < by) ||
+ (tree_cell_rect->x > (bx + visible_rect->width)) ||
+ (tree_cell_rect->y > (by + visible_rect->height)))
+ is_showing = FALSE;
+ else
+ is_showing = TRUE;
+
+ return is_showing;
+}
+
+/* Misc Public */
+
+/*
+ * This function is called when a cell's flyweight is created in
+ * gail_tree_view_table_ref_at with emit_change_signal set to FALSE
+ * and in model_row_changed() on receipt of "row-changed" signal when
+ * emit_change_signal is set to TRUE
+ */
+static gboolean
+update_cell_value (GailRendererCell *renderer_cell,
+ GailTreeView *gailview,
+ gboolean emit_change_signal)
+{
+ GailTreeViewCellInfo *cell_info;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ GList *renderers, *cur_renderer;
+ GParamSpec *spec;
+ GailRendererCellClass *gail_renderer_cell_class;
+ GtkCellRendererClass *gtk_cell_renderer_class;
+ GailCell *cell;
+ gchar **prop_list;
+ AtkObject *parent;
+ gboolean is_expander, is_expanded;
+
+ gail_renderer_cell_class = GAIL_RENDERER_CELL_GET_CLASS (renderer_cell);
+ if (renderer_cell->renderer)
+ gtk_cell_renderer_class = GTK_CELL_RENDERER_GET_CLASS (renderer_cell->renderer);
+ else
+ gtk_cell_renderer_class = NULL;
+
+ prop_list = gail_renderer_cell_class->property_list;
+
+ cell = GAIL_CELL (renderer_cell);
+ cell_info = find_cell_info (gailview, cell, NULL, TRUE);
+ gail_return_val_if_fail (cell_info, FALSE);
+ gail_return_val_if_fail (cell_info->cell_col_ref, FALSE);
+ gail_return_val_if_fail (cell_info->cell_row_ref, FALSE);
+
+ if (emit_change_signal && cell_info->in_use)
+ {
+ tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (gailview)));
+ tree_model = gtk_tree_view_get_model (tree_view);
+ path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ if (path == NULL)
+ return FALSE;
+
+ gtk_tree_model_get_iter (tree_model, &iter, path);
+ is_expander = FALSE;
+ is_expanded = FALSE;
+ if (gtk_tree_model_iter_has_child (tree_model, &iter))
+ {
+ GtkTreeViewColumn *expander_tv;
+
+ expander_tv = gtk_tree_view_get_expander_column (tree_view);
+ if (expander_tv == cell_info->cell_col_ref)
+ {
+ is_expander = TRUE;
+ is_expanded = gtk_tree_view_row_expanded (tree_view, path);
+ }
+ }
+ gtk_tree_path_free (path);
+ gtk_tree_view_column_cell_set_cell_data (cell_info->cell_col_ref,
+ tree_model, &iter, is_expander, is_expanded);
+ }
+ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cell_info->cell_col_ref));
+ gail_return_val_if_fail (renderers, FALSE);
+
+ /*
+ * If the cell is in a container, its index is used to find the renderer
+ * in the list
+ */
+
+ /*
+ * Otherwise, we assume that the cell is represented by the first renderer
+ * in the list
+ */
+
+ if (cell_info->in_use) {
+ parent = atk_object_get_parent (ATK_OBJECT (cell));
+ if (!ATK_IS_OBJECT (cell)) g_on_error_query (NULL);
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ cur_renderer = g_list_nth (renderers, cell->index);
+ else
+ cur_renderer = renderers;
+ }
+ else {
+ return FALSE;
+ }
+
+ gail_return_val_if_fail (cur_renderer != NULL, FALSE);
+
+ if (gtk_cell_renderer_class)
+ {
+ while (*prop_list)
+ {
+ spec = g_object_class_find_property
+ (G_OBJECT_CLASS (gtk_cell_renderer_class), *prop_list);
+
+ if (spec != NULL)
+ {
+ GValue value = { 0, };
+
+ g_value_init (&value, spec->value_type);
+ g_object_get_property (cur_renderer->data, *prop_list, &value);
+ g_object_set_property (G_OBJECT (renderer_cell->renderer),
+ *prop_list, &value);
+ g_value_unset(&value);
+ }
+ else
+ g_warning ("Invalid property: %s\n", *prop_list);
+ prop_list++;
+ }
+ }
+ g_list_free (renderers);
+ return gail_renderer_cell_update_cache (renderer_cell, emit_change_signal);
+}
+
+static void
+set_iter_nth_row (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ gint row)
+{
+ GtkTreeModel *tree_model;
+
+ tree_model = gtk_tree_view_get_model (tree_view);
+ gtk_tree_model_get_iter_first (tree_model, iter);
+ iter = return_iter_nth_row (tree_view, tree_model, iter, 0 , row);
+}
+
+static gint
+get_row_from_tree_path (GtkTreeView *tree_view,
+ GtkTreePath *path)
+{
+ GtkTreeModel *tree_model;
+ GtkTreePath *root_tree;
+ gint row;
+
+ tree_model = gtk_tree_view_get_model (tree_view);
+
+ if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
+ row = gtk_tree_path_get_indices (path)[0];
+ else
+ {
+ root_tree = gtk_tree_path_new_first ();
+ row = 0;
+ iterate_thru_children (tree_view, tree_model, root_tree, path, &row, 0);
+ gtk_tree_path_free (root_tree);
+ }
+
+ return row;
+}
+
+/* Misc Private */
+
+/*
+ * Get the specified GtkTreeViewColumn in the GtkTreeView.
+ * Only visible columns are considered.
+ */
+static GtkTreeViewColumn*
+get_column (GtkTreeView *tree_view,
+ gint in_col)
+{
+ GtkTreeViewColumn *tv_col;
+ gint n_cols = -1;
+ gint i = 0;
+
+ if (in_col < 0)
+ {
+ g_warning ("Request for invalid column %d\n", in_col);
+ return NULL;
+ }
+
+ tv_col = gtk_tree_view_get_column (tree_view, i);
+
+ while (tv_col != NULL)
+ {
+ if (gtk_tree_view_column_get_visible (tv_col))
+ n_cols++;
+ if (in_col == n_cols)
+ break;
+ tv_col = gtk_tree_view_get_column (tree_view, ++i);
+ }
+
+ if (in_col != n_cols)
+ {
+ g_warning ("Request for invalid column %d\n", in_col);
+ return NULL;
+ }
+ return tv_col;
+}
+
+static gint
+get_actual_column_number (GtkTreeView *tree_view,
+ gint visible_column)
+{
+ GtkTreeViewColumn *tv_col;
+ gint actual_column = 0;
+ gint visible_columns = -1;
+ /*
+ * This function calculates the column number which corresponds to the
+ * specified visible column number
+ */
+ tv_col = gtk_tree_view_get_column (tree_view, actual_column);
+
+ while (tv_col != NULL)
+ {
+ if (gtk_tree_view_column_get_visible (tv_col))
+ visible_columns++;
+ if (visible_columns == visible_column)
+ return actual_column;
+ tv_col = gtk_tree_view_get_column (tree_view, ++actual_column);
+ }
+ g_warning ("get_actual_column_number failed for %d\n", visible_column);
+ return -1;
+}
+
+static gint
+get_visible_column_number (GtkTreeView *tree_view,
+ gint actual_column)
+{
+ GtkTreeViewColumn *tv_col;
+ gint column = 0;
+ gint visible_columns = -1;
+ /*
+ * This function calculates the visible column number which corresponds to the
+ * specified actual column number
+ */
+ tv_col = gtk_tree_view_get_column (tree_view, column);
+
+ while (tv_col != NULL)
+ {
+ if (gtk_tree_view_column_get_visible (tv_col))
+ {
+ visible_columns++;
+ if (actual_column == column)
+ return visible_columns;
+ }
+ else
+ if (actual_column == column)
+ return -1;
+ tv_col = gtk_tree_view_get_column (tree_view, ++column);
+ }
+ g_warning ("get_visible_column_number failed for %d\n", actual_column);
+ return -1;
+}
+
+/**
+ * Helper recursive function that returns GtkTreeIter pointer to nth row.
+ **/
+static GtkTreeIter*
+return_iter_nth_row(GtkTreeView *tree_view,
+ GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ gint increment,
+ gint row)
+{
+ GtkTreePath *current_path = gtk_tree_model_get_path (tree_model, iter);
+ GtkTreeIter new_iter;
+ gboolean row_expanded;
+
+ if (increment == row) {
+ gtk_tree_path_free (current_path);
+ return iter;
+ }
+
+ row_expanded = gtk_tree_view_row_expanded (tree_view, current_path);
+ gtk_tree_path_free (current_path);
+
+ new_iter = *iter;
+ if ((row_expanded && gtk_tree_model_iter_children (tree_model, iter, &new_iter)) ||
+ (gtk_tree_model_iter_next (tree_model, iter)) ||
+ (gtk_tree_model_iter_parent (tree_model, iter, &new_iter) &&
+ (gtk_tree_model_iter_next (tree_model, iter))))
+ return return_iter_nth_row (tree_view, tree_model, iter,
+ ++increment, row);
+
+ return NULL;
+}
+
+/**
+ * Recursively called until the row specified by orig is found.
+ *
+ * *count will be set to the visible row number of the child
+ * relative to the row that was initially passed in as tree_path.
+ *
+ * *count will be -1 if orig is not found as a child (a row that is
+ * not visible will not be found, e.g. if the row is inside a
+ * collapsed row). If NULL is passed in as orig, *count will
+ * be a count of the visible children.
+ *
+ * NOTE: the value for depth must be 0 when this recursive function
+ * is initially called, or it may not function as expected.
+ **/
+static void
+iterate_thru_children(GtkTreeView *tree_view,
+ GtkTreeModel *tree_model,
+ GtkTreePath *tree_path,
+ GtkTreePath *orig,
+ gint *count,
+ gint depth)
+{
+ GtkTreeIter iter;
+
+ if (!gtk_tree_model_get_iter (tree_model, &iter, tree_path))
+ return;
+
+ if (tree_path && orig && !gtk_tree_path_compare (tree_path, orig))
+ /* Found it! */
+ return;
+
+ if (tree_path && orig && gtk_tree_path_compare (tree_path, orig) > 0)
+ {
+ /* Past it, so return -1 */
+ *count = -1;
+ return;
+ }
+ else if (gtk_tree_view_row_expanded (tree_view, tree_path) &&
+ gtk_tree_model_iter_has_child (tree_model, &iter))
+ {
+ (*count)++;
+ gtk_tree_path_append_index (tree_path, 0);
+ iterate_thru_children (tree_view, tree_model, tree_path,
+ orig, count, (depth + 1));
+ return;
+ }
+ else if (gtk_tree_model_iter_next (tree_model, &iter))
+ {
+ (*count)++;
+ tree_path = gtk_tree_model_get_path (tree_model, &iter);
+ if (tree_path)
+ {
+ iterate_thru_children (tree_view, tree_model, tree_path,
+ orig, count, depth);
+ gtk_tree_path_free (tree_path);
+ }
+ return;
+ }
+ else if (gtk_tree_path_up (tree_path))
+ {
+ GtkTreeIter temp_iter;
+ gboolean exit_loop = FALSE;
+ gint new_depth = depth - 1;
+
+ (*count)++;
+
+ /*
+ * Make sure that we back up until we find a row
+ * where gtk_tree_path_next does not return NULL.
+ */
+ while (!exit_loop)
+ {
+ if (gtk_tree_path_get_depth (tree_path) == 0)
+ /* depth is now zero so */
+ return;
+ gtk_tree_path_next (tree_path);
+
+ /* Verify that the next row is a valid row! */
+ exit_loop = gtk_tree_model_get_iter (tree_model, &temp_iter, tree_path);
+
+ if (!exit_loop)
+ {
+ /* Keep going up until we find a row that has a valid next */
+ if (gtk_tree_path_get_depth(tree_path) > 1)
+ {
+ new_depth--;
+ gtk_tree_path_up (tree_path);
+ }
+ else
+ {
+ /*
+ * If depth is 1 and gtk_tree_model_get_iter returns FALSE,
+ * then we are at the last row, so just return.
+ */
+ if (orig != NULL)
+ *count = -1;
+
+ return;
+ }
+ }
+ }
+
+ /*
+ * This guarantees that we will stop when we hit the end of the
+ * children.
+ */
+ if (new_depth < 0)
+ return;
+
+ iterate_thru_children (tree_view, tree_model, tree_path,
+ orig, count, new_depth);
+ return;
+ }
+
+ /*
+ * If it gets here, then the path wasn't found. Situations
+ * that would cause this would be if the path passed in is
+ * invalid or contained within the last row, but not visible
+ * because the last row is not expanded. If NULL was passed
+ * in then a row count is desired, so only set count to -1
+ * if orig is not NULL.
+ */
+ if (orig != NULL)
+ *count = -1;
+
+ return;
+}
+
+static void
+clean_cell_info (GailTreeView *gailview,
+ GList *list)
+{
+ GailTreeViewCellInfo *cell_info;
+ GObject *obj;
+
+ g_assert (GAIL_IS_TREE_VIEW (gailview));
+
+ cell_info = list->data;
+
+ if (cell_info->in_use) {
+ obj = G_OBJECT (cell_info->cell);
+
+ gail_cell_add_state (cell_info->cell, ATK_STATE_DEFUNCT, FALSE);
+ g_object_weak_unref (obj, (GWeakNotify) cell_destroyed, cell_info);
+ cell_info->in_use = FALSE;
+ if (!gailview->garbage_collection_pending) {
+ gailview->garbage_collection_pending = TRUE;
+ g_assert (gailview->idle_garbage_collect_id == 0);
+ gailview->idle_garbage_collect_id =
+ gdk_threads_add_idle (idle_garbage_collect_cell_data, gailview);
+ }
+ }
+}
+
+static void
+clean_rows (GailTreeView *gailview)
+{
+ GArray *array;
+
+ /* Clean GailTreeViewRowInfo data */
+
+ array = gailview->row_data;
+ if (array != NULL)
+ {
+ GailTreeViewRowInfo *row_info;
+ GtkTreePath *row_path;
+ gint i;
+
+ /*
+ * Loop backwards so that calls to free_row_info
+ * do not affect the index numbers
+ */
+ for (i = (array->len - 1); i >= 0; i --)
+ {
+ row_info = g_array_index (array, GailTreeViewRowInfo*, i);
+ row_path = gtk_tree_row_reference_get_path (row_info->row_ref);
+
+ /* Remove any rows that have become invalid */
+ if (row_path == NULL)
+ free_row_info (array, i, TRUE);
+ else
+ gtk_tree_path_free (row_path);
+ }
+ }
+
+ /* Clean GailTreeViewCellInfo data */
+
+ if (gailview->cell_data != NULL)
+ {
+ GailTreeViewCellInfo *cell_info;
+ GtkTreePath *row_path;
+ GList *cur_list;
+ GList *temp_list;
+
+ temp_list = gailview->cell_data;
+
+ /* Must loop through them all */
+ while (temp_list != NULL)
+ {
+ cur_list = temp_list;
+ cell_info = temp_list->data;
+ temp_list = temp_list->next;
+ row_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+
+ /*
+ * If the cell has become invalid because the row has been removed,
+ * then set the cell's state to ATK_STATE_DEFUNCT and remove the cell
+ * from gailview->cell_data. If row_path is NULL then the row has
+ * been removed.
+ */
+ if (row_path == NULL)
+ {
+ clean_cell_info (gailview, cur_list);
+ }
+ else
+ {
+ gtk_tree_path_free (row_path);
+ }
+ }
+ }
+}
+
+static void
+clean_cols (GailTreeView *gailview,
+ GtkTreeViewColumn *tv_col)
+{
+ /* Clean GailTreeViewCellInfo data */
+
+ if (gailview->cell_data != NULL)
+ {
+ GailTreeViewCellInfo *cell_info;
+ GList *cur_list, *temp_list;
+
+ temp_list = gailview->cell_data;
+
+ while (temp_list != NULL)
+ {
+ cur_list = temp_list;
+ cell_info = temp_list->data;
+ temp_list = temp_list->next;
+
+ /*
+ * If the cell has become invalid because the column tv_col
+ * has been removed, then set the cell's state to ATK_STATE_DEFUNCT
+ * and remove the cell from gailview->cell_data.
+ */
+ if (cell_info->cell_col_ref == tv_col)
+ {
+ clean_cell_info (gailview, cur_list);
+ }
+ }
+ }
+}
+
+static gboolean
+idle_garbage_collect_cell_data (gpointer data)
+{
+ GailTreeView *tree_view;
+
+ g_assert (GAIL_IS_TREE_VIEW (data));
+ tree_view = (GailTreeView *)data;
+
+ /* this is the idle handler (only one instance allowed), so
+ * we can safely delete it.
+ */
+ tree_view->garbage_collection_pending = FALSE;
+ tree_view->idle_garbage_collect_id = 0;
+
+ tree_view->garbage_collection_pending = garbage_collect_cell_data (data);
+
+ /* N.B.: if for some reason another handler has re-enterantly been queued
+ * while this handler was being serviced, it has its own gsource, therefore this handler
+ * should always return FALSE.
+ */
+ return FALSE;
+}
+
+static gboolean
+garbage_collect_cell_data (gpointer data)
+{
+ GailTreeView *tree_view;
+ GList *temp_list, *list;
+ GailTreeViewCellInfo *cell_info;
+
+ g_assert (GAIL_IS_TREE_VIEW (data));
+ tree_view = (GailTreeView *)data;
+ list = g_list_copy (tree_view->cell_data);
+
+ tree_view->garbage_collection_pending = FALSE;
+ if (tree_view->idle_garbage_collect_id != 0)
+ {
+ g_source_remove (tree_view->idle_garbage_collect_id);
+ tree_view->idle_garbage_collect_id = 0;
+ }
+
+ /* Must loop through them all */
+ temp_list = list;
+ while (temp_list != NULL)
+ {
+ cell_info = temp_list->data;
+ if (!cell_info->in_use)
+ {
+ /* g_object_unref (cell_info->cell); */
+ tree_view->cell_data = g_list_remove (tree_view->cell_data,
+ cell_info);
+ if (cell_info->cell_row_ref)
+ gtk_tree_row_reference_free (cell_info->cell_row_ref);
+ g_free (cell_info);
+ }
+ temp_list = temp_list->next;
+ }
+ g_list_free (list);
+
+ return tree_view->garbage_collection_pending;
+}
+
+/**
+ * If tree_path is passed in as NULL, then all cells are acted on.
+ * Otherwise, just act on those cells that are on a row greater than
+ * the specified tree_path. If inc_row is passed in as TRUE, then rows
+ * greater and equal to the specified tree_path are acted on.
+ *
+ * if set_stale is set the ATK_STATE_STALE is set on cells which are to be
+ * acted on.
+ *
+ * The function set_cell_visibility() is called on all cells to be
+ * acted on to update the visibility of the cell.
+ **/
+static void
+traverse_cells (GailTreeView *tree_view,
+ GtkTreePath *tree_path,
+ gboolean set_stale,
+ gboolean inc_row)
+{
+ if (tree_view->cell_data != NULL)
+ {
+ GailTreeViewCellInfo *cell_info;
+ GtkTreeView *gtk_tree_view;
+ GList *temp_list;
+ GtkWidget *widget;
+
+ g_assert (GTK_IS_ACCESSIBLE (tree_view));
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (tree_view));
+ if (!widget)
+ /* Widget is being deleted */
+ return;
+
+ gtk_tree_view = GTK_TREE_VIEW (widget);
+ temp_list = tree_view->cell_data;
+
+ /* Must loop through them all */
+ while (temp_list != NULL)
+ {
+ GtkTreePath *row_path;
+ gboolean act_on_cell;
+
+ cell_info = temp_list->data;
+ temp_list = temp_list->next;
+
+ if (cell_info->in_use)
+ {
+ row_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ g_return_if_fail (row_path != NULL);
+ if (tree_path == NULL)
+ act_on_cell = TRUE;
+ else
+ {
+ gint comparison;
+
+ comparison = gtk_tree_path_compare (row_path, tree_path);
+ if ((comparison > 0) ||
+ (comparison == 0 && inc_row))
+ act_on_cell = TRUE;
+ else
+ act_on_cell = FALSE;
+ }
+ if (!cell_info->in_use) g_warning ("warning: cell info destroyed during traversal");
+ if (act_on_cell && cell_info->in_use)
+ {
+ if (set_stale)
+ gail_cell_add_state (cell_info->cell, ATK_STATE_STALE, TRUE);
+ set_cell_visibility (gtk_tree_view,
+ cell_info->cell,
+ cell_info->cell_col_ref,
+ row_path, TRUE);
+ }
+ gtk_tree_path_free (row_path);
+ }
+ }
+ }
+ g_signal_emit_by_name (tree_view, "visible-data-changed");
+}
+
+static void
+free_row_info (GArray *array,
+ gint array_idx,
+ gboolean shift)
+{
+ GailTreeViewRowInfo* obj;
+
+ obj = g_array_index (array, GailTreeViewRowInfo*, array_idx);
+
+ g_free (obj->description);
+ if (obj->row_ref != NULL)
+ gtk_tree_row_reference_free (obj->row_ref);
+ if (obj->header)
+ g_object_unref (obj->header);
+ g_free (obj);
+
+ if (shift)
+ g_array_remove_index (array, array_idx);
+}
+
+/*
+ * If the tree_path passed in has children, then
+ * ATK_STATE_EXPANDABLE is set. If the row is expanded
+ * ATK_STATE_EXPANDED is turned on. If the row is
+ * collapsed, then ATK_STATE_EXPANDED is removed.
+ *
+ * If the tree_path passed in has no children, then
+ * ATK_STATE_EXPANDABLE and ATK_STATE_EXPANDED are removed.
+ *
+ * If set_on_ancestor is TRUE, then this function will also
+ * update all cells that are ancestors of the tree_path.
+ */
+static void
+set_expand_state (GtkTreeView *tree_view,
+ GtkTreeModel *tree_model,
+ GailTreeView *gailview,
+ GtkTreePath *tree_path,
+ gboolean set_on_ancestor)
+{
+ if (gailview->cell_data != NULL)
+ {
+ GtkTreeViewColumn *expander_tv;
+ GailTreeViewCellInfo *cell_info;
+ GList *temp_list;
+ GtkTreePath *cell_path;
+ GtkTreeIter iter;
+ gboolean found;
+
+ temp_list = gailview->cell_data;
+
+ while (temp_list != NULL)
+ {
+ cell_info = temp_list->data;
+ temp_list = temp_list->next;
+ if (cell_info->in_use)
+ {
+ cell_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ found = FALSE;
+
+ if (cell_path != NULL)
+ {
+ GailCell *cell = GAIL_CELL (cell_info->cell);
+
+ expander_tv = gtk_tree_view_get_expander_column (tree_view);
+
+ /*
+ * Only set state for the cell that is in the column with the
+ * expander toggle
+ */
+ if (expander_tv == cell_info->cell_col_ref)
+ {
+ if (tree_path && gtk_tree_path_compare (cell_path, tree_path) == 0)
+ found = TRUE;
+ else if (set_on_ancestor &&
+ gtk_tree_path_get_depth (cell_path) <
+ gtk_tree_path_get_depth (tree_path) &&
+ gtk_tree_path_is_ancestor (cell_path, tree_path) == 1)
+ /* Only set if set_on_ancestor was passed in as TRUE */
+ found = TRUE;
+ }
+
+ /*
+ * Set ATK_STATE_EXPANDABLE and ATK_STATE_EXPANDED
+ * for ancestors and found cells.
+ */
+ if (found)
+ {
+ /*
+ * Must check against cell_path since cell_path
+ * can be equal to or an ancestor of tree_path.
+ */
+ gtk_tree_model_get_iter (tree_model, &iter, cell_path);
+
+ /* Set or unset ATK_STATE_EXPANDABLE as appropriate */
+ if (gtk_tree_model_iter_has_child (tree_model, &iter))
+ {
+ set_cell_expandable (cell);
+
+ if (gtk_tree_view_row_expanded (tree_view, cell_path))
+ gail_cell_add_state (cell, ATK_STATE_EXPANDED, TRUE);
+ else
+ gail_cell_remove_state (cell,
+ ATK_STATE_EXPANDED, TRUE);
+ }
+ else
+ {
+ gail_cell_remove_state (cell,
+ ATK_STATE_EXPANDED, TRUE);
+ if (gail_cell_remove_state (cell,
+ ATK_STATE_EXPANDABLE, TRUE))
+ /* The state may have been propagated to the container cell */
+ if (!GAIL_IS_CONTAINER_CELL (cell))
+ gail_cell_remove_action_by_name (cell,
+ "expand or contract");
+ }
+
+ /*
+ * We assume that each cell in the cache once and
+ * a container cell is before its child cells so we are
+ * finished if set_on_ancestor is not set to TRUE.
+ */
+ if (!set_on_ancestor)
+ break;
+ }
+ }
+ gtk_tree_path_free (cell_path);
+ }
+ }
+ }
+}
+
+
+static void
+add_cell_actions (GailCell *cell,
+ gboolean editable)
+{
+ if (GAIL_IS_BOOLEAN_CELL (cell))
+ gail_cell_add_action (cell,
+ "toggle",
+ "toggles the cell", /* action description */
+ NULL,
+ toggle_cell_toggled);
+ if (editable)
+ gail_cell_add_action (cell,
+ "edit",
+ "creates a widget in which the contents of the cell can be edited",
+ NULL,
+ edit_cell);
+ gail_cell_add_action (cell,
+ "activate",
+ "activate the cell",
+ NULL,
+ activate_cell);
+}
+
+static void
+toggle_cell_expanded (GailCell *cell)
+{
+ GailTreeViewCellInfo *cell_info;
+ GtkTreeView *tree_view;
+ GtkTreePath *path;
+ AtkObject *parent;
+ AtkStateSet *stateset;
+
+ parent = atk_object_get_parent (ATK_OBJECT (cell));
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ parent = atk_object_get_parent (parent);
+
+ cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
+ gail_return_if_fail (cell_info);
+ gail_return_if_fail (cell_info->cell_col_ref);
+ gail_return_if_fail (cell_info->cell_row_ref);
+
+ tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)));
+ path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ gail_return_if_fail (path);
+
+ stateset = atk_object_ref_state_set (ATK_OBJECT (cell));
+ if (atk_state_set_contains_state (stateset, ATK_STATE_EXPANDED))
+ gtk_tree_view_collapse_row (tree_view, path);
+ else
+ gtk_tree_view_expand_row (tree_view, path, TRUE);
+ g_object_unref (stateset);
+ gtk_tree_path_free (path);
+ return;
+}
+
+static void
+toggle_cell_toggled (GailCell *cell)
+{
+ GailTreeViewCellInfo *cell_info;
+ GtkTreePath *path;
+ gchar *pathstring;
+ GList *renderers, *cur_renderer;
+ AtkObject *parent;
+ gboolean is_container_cell = FALSE;
+
+ parent = atk_object_get_parent (ATK_OBJECT (cell));
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ {
+ is_container_cell = TRUE;
+ parent = atk_object_get_parent (parent);
+ }
+
+ cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
+ gail_return_if_fail (cell_info);
+ gail_return_if_fail (cell_info->cell_col_ref);
+ gail_return_if_fail (cell_info->cell_row_ref);
+
+ path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ gail_return_if_fail (path);
+ pathstring = gtk_tree_path_to_string (path);
+
+ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cell_info->cell_col_ref));
+ gail_return_if_fail (renderers);
+
+ /*
+ * if the cell is in a container, its index is used to find the
+ * renderer in the list
+ */
+
+ if (is_container_cell)
+ cur_renderer = g_list_nth (renderers, cell->index);
+ else
+ /*
+ * Otherwise, we assume that the cell is represented by the first
+ * renderer in the list
+ */
+ cur_renderer = renderers;
+
+ gail_return_if_fail (cur_renderer);
+
+ g_signal_emit_by_name (cur_renderer->data, "toggled", pathstring);
+ g_list_free (renderers);
+ g_free (pathstring);
+ gtk_tree_path_free (path);
+ return;
+}
+
+static void
+edit_cell (GailCell *cell)
+{
+ GailTreeViewCellInfo *cell_info;
+ GtkTreeView *tree_view;
+ GtkTreePath *path;
+ AtkObject *parent;
+
+ editing = TRUE;
+ parent = atk_object_get_parent (ATK_OBJECT (cell));
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ parent = atk_object_get_parent (parent);
+
+ cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
+ gail_return_if_fail (cell_info);
+ gail_return_if_fail (cell_info->cell_col_ref);
+ gail_return_if_fail (cell_info->cell_row_ref);
+
+ tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)));
+ path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ gail_return_if_fail (path);
+ gtk_tree_view_set_cursor (tree_view, path, cell_info->cell_col_ref, TRUE);
+ gtk_tree_path_free (path);
+ return;
+}
+
+static void
+activate_cell (GailCell *cell)
+{
+ GailTreeViewCellInfo *cell_info;
+ GtkTreeView *tree_view;
+ GtkTreePath *path;
+ AtkObject *parent;
+
+ editing = TRUE;
+ parent = atk_object_get_parent (ATK_OBJECT (cell));
+ if (GAIL_IS_CONTAINER_CELL (parent))
+ parent = atk_object_get_parent (parent);
+
+ cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
+ gail_return_if_fail (cell_info);
+ gail_return_if_fail (cell_info->cell_col_ref);
+ gail_return_if_fail (cell_info->cell_row_ref);
+
+ tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)));
+ path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
+ gail_return_if_fail (path);
+ gtk_tree_view_row_activated (tree_view, path, cell_info->cell_col_ref);
+ gtk_tree_path_free (path);
+ return;
+}
+
+static void
+cell_destroyed (gpointer data)
+{
+ GailTreeViewCellInfo *cell_info = data;
+
+ gail_return_if_fail (cell_info);
+ if (cell_info->in_use) {
+ cell_info->in_use = FALSE;
+
+ g_assert (GAIL_IS_TREE_VIEW (cell_info->view));
+ if (!cell_info->view->garbage_collection_pending) {
+ cell_info->view->garbage_collection_pending = TRUE;
+ cell_info->view->idle_garbage_collect_id =
+ gdk_threads_add_idle (idle_garbage_collect_cell_data, cell_info->view);
+ }
+ }
+}
+
+#if 0
+static void
+cell_info_remove (GailTreeView *tree_view,
+ GailCell *cell)
+{
+ GailTreeViewCellInfo *info;
+ GList *temp_list;
+
+ info = find_cell_info (tree_view, cell, &temp_list, FALSE);
+ if (info)
+ {
+ info->in_use = FALSE;
+ return;
+ }
+ g_warning ("No cell removed in cell_info_remove\n");
+}
+#endif
+
+static void
+cell_info_get_index (GtkTreeView *tree_view,
+ GailTreeViewCellInfo *info,
+ gint *index)
+{
+ GtkTreePath *path;
+ gint column_number;
+
+ path = gtk_tree_row_reference_get_path (info->cell_row_ref);
+ gail_return_if_fail (path);
+
+ column_number = get_column_number (tree_view, info->cell_col_ref, FALSE);
+ *index = get_index (tree_view, path, column_number);
+ gtk_tree_path_free (path);
+}
+
+static void
+cell_info_new (GailTreeView *gailview,
+ GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeViewColumn *tv_col,
+ GailCell *cell )
+{
+ GailTreeViewCellInfo *cell_info;
+
+ g_assert (GAIL_IS_TREE_VIEW (gailview));
+
+ cell_info = g_new (GailTreeViewCellInfo, 1);
+ cell_info->cell_row_ref = gtk_tree_row_reference_new (tree_model, path);
+
+ cell_info->cell_col_ref = tv_col;
+ cell_info->cell = cell;
+ cell_info->in_use = TRUE; /* if we've created it, assume it's in use */
+ cell_info->view = gailview;
+ gailview->cell_data = g_list_append (gailview->cell_data, cell_info);
+
+ /* Setup weak reference notification */
+
+ g_object_weak_ref (G_OBJECT (cell),
+ (GWeakNotify) cell_destroyed,
+ cell_info);
+}
+
+static GailCell*
+find_cell (GailTreeView *gailview,
+ gint index)
+{
+ GailTreeViewCellInfo *info;
+ GtkTreeView *tree_view;
+ GList *cell_list;
+ GList *l;
+ gint real_index;
+ gboolean needs_cleaning = FALSE;
+ GailCell *retval = NULL;
+
+ tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (gailview)));
+ cell_list = gailview->cell_data;
+
+ for (l = cell_list; l; l = l->next)
+ {
+ info = (GailTreeViewCellInfo *) (l->data);
+ if (info->in_use)
+ {
+ cell_info_get_index (tree_view, info, &real_index);
+ if (index == real_index)
+ {
+ retval = info->cell;
+ break;
+ }
+ }
+ else
+ {
+ needs_cleaning = TRUE;
+ }
+ }
+ if (needs_cleaning)
+ garbage_collect_cell_data (gailview);
+
+ return retval;
+}
+
+static void
+refresh_cell_index (GailCell *cell)
+{
+ GailTreeViewCellInfo *info;
+ AtkObject *parent;
+ GtkTreeView *tree_view;
+ gint index;
+
+ parent = atk_object_get_parent (ATK_OBJECT (cell));
+ gail_return_if_fail (GAIL_IS_TREE_VIEW (parent));
+
+ tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)));
+
+ /* Find this cell in the GailTreeView's cache */
+
+ info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
+ gail_return_if_fail (info);
+
+ cell_info_get_index (tree_view, info, &index);
+ cell->index = index;
+}
+
+static void
+get_selected_rows (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ GPtrArray *array = (GPtrArray *)data;
+
+ g_ptr_array_add (array, gtk_tree_path_copy (path));
+}
+
+static void
+connect_model_signals (GtkTreeView *view,
+ GailTreeView *gailview)
+{
+ GObject *obj;
+
+ obj = G_OBJECT (gailview->tree_model);
+ g_signal_connect_data (obj, "row-changed",
+ (GCallback) model_row_changed, view, NULL, 0);
+ g_signal_connect_data (obj, "row-inserted",
+ (GCallback) model_row_inserted, view, NULL,
+ G_CONNECT_AFTER);
+ g_signal_connect_data (obj, "row-deleted",
+ (GCallback) model_row_deleted, view, NULL,
+ G_CONNECT_AFTER);
+ g_signal_connect_data (obj, "rows-reordered",
+ (GCallback) model_rows_reordered, view, NULL,
+ G_CONNECT_AFTER);
+}
+
+static void
+disconnect_model_signals (GailTreeView *view)
+{
+ GObject *obj;
+ GtkWidget *widget;
+
+ obj = G_OBJECT (view->tree_model);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (view));
+ g_signal_handlers_disconnect_by_func (obj, (gpointer) model_row_changed, widget);
+ g_signal_handlers_disconnect_by_func (obj, (gpointer) model_row_inserted, widget);
+ g_signal_handlers_disconnect_by_func (obj, (gpointer) model_row_deleted, widget);
+ g_signal_handlers_disconnect_by_func (obj, (gpointer) model_rows_reordered, widget);
+}
+
+static void
+clear_cached_data (GailTreeView *view)
+{
+ GList *temp_list;
+
+ if (view->row_data)
+ {
+ GArray *array = view->row_data;
+ gint i;
+
+ /*
+ * Since the third argument to free_row_info is FALSE, we don't remove
+ * the element. Therefore it is safe to loop forward.
+ */
+ for (i = 0; i < array->len; i++)
+ free_row_info (array, i, FALSE);
+
+ g_array_free (array, TRUE);
+
+ view->row_data = NULL;
+ }
+
+ if (view->cell_data)
+ {
+ /* Must loop through them all */
+ for (temp_list = view->cell_data; temp_list; temp_list = temp_list->next)
+ {
+ clean_cell_info (view, temp_list);
+ }
+ }
+ garbage_collect_cell_data (view);
+ if (view->cell_data)
+ g_list_free (view->cell_data);
+
+ view->cell_data = NULL;
+}
+
+/*
+ * Returns the column number of the specified GtkTreeViewColumn
+ *
+ * If visible is set, the value returned will be the visible column number,
+ * i.e. suitable for use in AtkTable function. If visible is not set, the
+ * value returned is the actual column number, which is suitable for use in
+ * getting an index value.
+ */
+static gint
+get_column_number (GtkTreeView *tree_view,
+ GtkTreeViewColumn *column,
+ gboolean visible)
+{
+ GList *temp_list, *column_list;
+ GtkTreeViewColumn *tv_column;
+ gint ret_val;
+
+ column_list = gtk_tree_view_get_columns (tree_view);
+ ret_val = 0;
+ for (temp_list = column_list; temp_list; temp_list = temp_list->next)
+ {
+ tv_column = GTK_TREE_VIEW_COLUMN (temp_list->data);
+ if (tv_column == column)
+ break;
+ if (!visible || gtk_tree_view_column_get_visible (tv_column))
+ ret_val++;
+ }
+ if (temp_list == NULL)
+ {
+ ret_val = -1;
+ }
+ g_list_free (column_list);
+ return ret_val;
+}
+
+static gint
+get_index (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ gint actual_column)
+{
+ gint depth = 0;
+ gint index = 1;
+ gint *indices = NULL;
+
+
+ if (path)
+ {
+ depth = gtk_tree_path_get_depth (path);
+ indices = gtk_tree_path_get_indices (path);
+ }
+
+ if (depth > 1)
+ {
+ GtkTreePath *copy_path;
+ GtkTreeModel *model;
+
+ model = gtk_tree_view_get_model (tree_view);
+ copy_path = gtk_tree_path_copy (path);
+ gtk_tree_path_up (copy_path);
+ count_rows (model, NULL, copy_path, &index, 0, depth);
+ gtk_tree_path_free (copy_path);
+ }
+
+ if (path)
+ index += indices[depth-1];
+ index *= get_n_actual_columns (tree_view);
+ index += actual_column;
+ return index;
+}
+
+/*
+ * The function count_rows counts the number of rows starting at iter and ending
+ * at end_path. The value of level is the depth of iter and the value of depth
+ * is the depth of end_path. Rows at depth before end_path are counted.
+ * This functions counts rows which are not visible because an ancestor is
+ * collapsed.
+ */
+static void
+count_rows (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkTreePath *end_path,
+ gint *count,
+ gint level,
+ gint depth)
+{
+ GtkTreeIter child_iter;
+
+ if (!model) return;
+
+ level++;
+
+ *count += gtk_tree_model_iter_n_children (model, iter);
+
+#if 0
+ g_print ("count_rows : %d level: %d depth: %d\n", *count, level, depth);
+ if (iter != NULL)
+ g_print ("path: %s\n",
+ gtk_tree_path_to_string (gtk_tree_model_get_path (model, iter)));
+#endif
+
+ if (level >= depth)
+ return;
+
+ if (gtk_tree_model_iter_children (model, &child_iter, iter))
+ {
+ gboolean ret_val = TRUE;
+
+ while (ret_val)
+ {
+ if (level == depth - 1)
+ {
+ GtkTreePath *iter_path;
+ gboolean finished = FALSE;
+
+ iter_path = gtk_tree_model_get_path (model, &child_iter);
+ if (end_path && gtk_tree_path_compare (iter_path, end_path) >= 0)
+ finished = TRUE;
+ gtk_tree_path_free (iter_path);
+ if (finished)
+ break;
+ }
+ if (gtk_tree_model_iter_has_child (model, &child_iter))
+ count_rows (model, &child_iter, end_path, count, level, depth);
+ ret_val = gtk_tree_model_iter_next (model, &child_iter);
+ }
+ }
+}
+
+/*
+ * Find the next node, which has children, at the specified depth below
+ * the specified iter. The level is the depth of the current iter.
+ * The position of the node is returned in path and the return value of TRUE
+ * means that a node was found.
+ */
+
+gboolean get_next_node_with_child_at_depth (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkTreePath **path,
+ gint level,
+ gint depth)
+{
+ GtkTreeIter child_iter;
+
+ *path = NULL;
+
+ if (gtk_tree_model_iter_children (model, &child_iter, iter))
+ {
+ level++;
+
+ while (TRUE)
+ {
+ while (!gtk_tree_model_iter_has_child (model, &child_iter))
+ {
+ if (!gtk_tree_model_iter_next (model, &child_iter))
+ return FALSE;
+ }
+
+ if (level == depth)
+ /* We have found what we were looking for */
+ {
+ *path = gtk_tree_model_get_path (model, &child_iter);
+ return TRUE;
+ }
+
+ if (get_next_node_with_child_at_depth (model, &child_iter, path,
+ level, depth))
+ return TRUE;
+
+ if (!gtk_tree_model_iter_next (model, &child_iter))
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Find the next node, which has children, at the same depth as
+ * the specified GtkTreePath.
+ */
+static gboolean
+get_next_node_with_child (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreePath **return_path)
+{
+ GtkTreeIter iter;
+ gint depth;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+
+ while (gtk_tree_model_iter_next (model, &iter))
+ {
+ if (gtk_tree_model_iter_has_child (model, &iter))
+ {
+ *return_path = gtk_tree_model_get_path (model, &iter);
+ return TRUE;
+ }
+ }
+ depth = gtk_tree_path_get_depth (path);
+ while (gtk_tree_path_up (path))
+ {
+ if (gtk_tree_path_get_depth (path) == 0)
+ break;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ while (gtk_tree_model_iter_next (model, &iter))
+ if (get_next_node_with_child_at_depth (model, &iter, return_path,
+ gtk_tree_path_get_depth (path), depth))
+ return TRUE;
+ }
+ *return_path = NULL;
+ return FALSE;
+}
+
+static gboolean
+get_tree_path_from_row_index (GtkTreeModel *model,
+ gint row_index,
+ GtkTreePath **tree_path)
+{
+ GtkTreeIter iter;
+ gint count;
+ gint depth;
+
+ count = gtk_tree_model_iter_n_children (model, NULL);
+ if (count > row_index)
+ {
+ if (gtk_tree_model_iter_nth_child (model, &iter, NULL, row_index))
+ {
+ *tree_path = gtk_tree_model_get_path (model, &iter);
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+ else
+ row_index -= count;
+
+ depth = 0;
+ while (TRUE)
+ {
+ depth++;
+
+ if (get_next_node_with_child_at_depth (model, NULL, tree_path, 0, depth))
+ {
+ GtkTreePath *next_path;
+
+ while (TRUE)
+ {
+ gtk_tree_model_get_iter (model, &iter, *tree_path);
+ count = gtk_tree_model_iter_n_children (model, &iter);
+ if (count > row_index)
+ {
+ gtk_tree_path_append_index (*tree_path, row_index);
+ return TRUE;
+ }
+ else
+ row_index -= count;
+
+ if (!get_next_node_with_child (model, *tree_path, &next_path))
+ break;
+
+ gtk_tree_path_free (*tree_path);
+ *tree_path = next_path;
+ }
+ }
+ else
+ {
+ g_warning ("Index value is too large\n");
+ gtk_tree_path_free (*tree_path);
+ *tree_path = NULL;
+ return FALSE;
+ }
+ }
+}
+
+/*
+ * This function returns the number of rows, including those which are collapsed
+ */
+static gint
+get_row_count (GtkTreeModel *model)
+{
+ gint n_rows = 1;
+
+ count_rows (model, NULL, NULL, &n_rows, 0, G_MAXINT);
+
+ return n_rows;
+}
+
+static gboolean
+get_path_column_from_index (GtkTreeView *tree_view,
+ gint index,
+ GtkTreePath **path,
+ GtkTreeViewColumn **column)
+{
+ GtkTreeModel *tree_model;
+ gint n_columns;
+
+ tree_model = gtk_tree_view_get_model (tree_view);
+ n_columns = get_n_actual_columns (tree_view);
+ if (n_columns == 0)
+ return FALSE;
+ /* First row is the column headers */
+ index -= n_columns;
+ if (index < 0)
+ return FALSE;
+
+ if (path)
+ {
+ gint row_index;
+ gboolean retval;
+
+ row_index = index / n_columns;
+ retval = get_tree_path_from_row_index (tree_model, row_index, path);
+ gail_return_val_if_fail (retval, FALSE);
+ if (*path == NULL)
+ return FALSE;
+ }
+
+ if (column)
+ {
+ *column = gtk_tree_view_get_column (tree_view, index % n_columns);
+ if (*column == NULL)
+ {
+ if (path)
+ gtk_tree_path_free (*path);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+set_cell_expandable (GailCell *cell)
+{
+ if (gail_cell_add_state (cell,
+ ATK_STATE_EXPANDABLE,
+ FALSE))
+ gail_cell_add_action (cell,
+ "expand or contract", /* action name */
+ "expands or contracts the row in the tree view "
+ "containing this cell", /* description */
+ NULL, /* Keybinding */
+ toggle_cell_expanded);
+}
+
+static GailTreeViewCellInfo*
+find_cell_info (GailTreeView *view,
+ GailCell *cell,
+ GList** list,
+ gboolean live_only)
+{
+ GList *temp_list;
+ GailTreeViewCellInfo *cell_info;
+
+ for (temp_list = view->cell_data; temp_list; temp_list = temp_list->next)
+ {
+ cell_info = (GailTreeViewCellInfo *) temp_list->data;
+ if (cell_info->cell == cell && (!live_only || cell_info->in_use))
+ {
+ if (list)
+ *list = temp_list;
+ return cell_info;
+ }
+ }
+ return NULL;
+}
+
+static AtkObject *
+get_header_from_column (GtkTreeViewColumn *tv_col)
+{
+ AtkObject *rc;
+ GtkWidget *header_widget;
+
+ if (tv_col == NULL)
+ return NULL;
+
+ /* If the user has set a header object, use that */
+
+ rc = g_object_get_qdata (G_OBJECT (tv_col), quark_column_header_object);
+
+ if (rc == NULL)
+ {
+ /* If the user has not set a header object, grab the column */
+ /* header object defined by the GtkTreeView */
+
+ header_widget = gtk_tree_view_column_get_button (tv_col);
+
+ if (header_widget)
+ {
+ rc = gtk_widget_get_accessible (header_widget);
+ }
+ else
+ rc = NULL;
+ }
+ return rc;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_TREE_VIEW_H__
+#define __GAIL_TREE_VIEW_H__
+
+#include <gtk/gtk.h>
+#include "gailcontainer.h"
+#include "gailcell.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_TREE_VIEW (gail_tree_view_get_type ())
+#define GAIL_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TREE_VIEW, GailTreeView))
+#define GAIL_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TREE_VIEW, GailTreeViewClass))
+#define GAIL_IS_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TREE_VIEW))
+#define GAIL_IS_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TREE_VIEW))
+#define GAIL_TREE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TREE_VIEW, GailTreeViewClass))
+
+typedef struct _GailTreeView GailTreeView;
+typedef struct _GailTreeViewClass GailTreeViewClass;
+
+struct _GailTreeView
+{
+ GailContainer parent;
+
+ AtkObject* caption;
+ AtkObject* summary;
+ gint n_children_deleted;
+ GArray* col_data;
+ GArray* row_data;
+ GList* cell_data;
+ GtkTreeModel *tree_model;
+ AtkObject *focus_cell;
+ GtkAdjustment *old_hadj;
+ GtkAdjustment *old_vadj;
+ guint idle_expand_id;
+ guint idle_garbage_collect_id;
+ guint idle_cursor_changed_id;
+ GtkTreePath *idle_expand_path;
+ gboolean garbage_collection_pending;
+};
+
+GType gail_tree_view_get_type (void);
+
+struct _GailTreeViewClass
+{
+ GailContainerClass parent_class;
+};
+
+AtkObject* gail_tree_view_ref_focus_cell (GtkTreeView *treeview);
+
+G_END_DECLS
+
+#endif /* __GAIL_TREE_VIEW_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include "gailutil.h"
+#include "gailtoplevel.h"
+#include "gailwindow.h"
+#include "gail-private-macros.h"
+
+static void gail_util_class_init (GailUtilClass *klass);
+static void gail_util_init (GailUtil *utils);
+/* atkutil.h */
+
+static guint gail_util_add_global_event_listener (GSignalEmissionHook listener,
+ const gchar* event_type);
+static void gail_util_remove_global_event_listener (guint remove_listener);
+static guint gail_util_add_key_event_listener (AtkKeySnoopFunc listener,
+ gpointer data);
+static void gail_util_remove_key_event_listener (guint remove_listener);
+static AtkObject* gail_util_get_root (void);
+static const gchar *gail_util_get_toolkit_name (void);
+static const gchar *gail_util_get_toolkit_version (void);
+
+/* gailmisc/AtkMisc */
+static void gail_misc_class_init (GailMiscClass *klass);
+static void gail_misc_init (GailMisc *misc);
+
+static void gail_misc_threads_enter (AtkMisc *misc);
+static void gail_misc_threads_leave (AtkMisc *misc);
+
+/* Misc */
+
+static void _listener_info_destroy (gpointer data);
+static guint add_listener (GSignalEmissionHook listener,
+ const gchar *object_type,
+ const gchar *signal,
+ const gchar *hook_data);
+static void do_window_event_initialization (void);
+static gboolean state_event_watcher (GSignalInvocationHint *hint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static void window_added (AtkObject *atk_obj,
+ guint index,
+ AtkObject *child);
+static void window_removed (AtkObject *atk_obj,
+ guint index,
+ AtkObject *child);
+static gboolean window_focus (GtkWidget *widget,
+ GdkEventFocus *event);
+static gboolean configure_event_watcher (GSignalInvocationHint *hint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+
+
+static AtkObject* root = NULL;
+static GHashTable *listener_list = NULL;
+static gint listener_idx = 1;
+static GSList *key_listener_list = NULL;
+static guint key_snooper_id = 0;
+
+typedef struct _GailUtilListenerInfo GailUtilListenerInfo;
+typedef struct _GailKeyEventInfo GailKeyEventInfo;
+
+struct _GailUtilListenerInfo
+{
+ gint key;
+ guint signal_id;
+ gulong hook_id;
+};
+
+struct _GailKeyEventInfo
+{
+ AtkKeyEventStruct *key_event;
+ gpointer func_data;
+};
+
+G_DEFINE_TYPE (GailUtil, gail_util, ATK_TYPE_UTIL)
+
+static void
+gail_util_class_init (GailUtilClass *klass)
+{
+ AtkUtilClass *atk_class;
+ gpointer data;
+
+ data = g_type_class_peek (ATK_TYPE_UTIL);
+ atk_class = ATK_UTIL_CLASS (data);
+
+ atk_class->add_global_event_listener =
+ gail_util_add_global_event_listener;
+ atk_class->remove_global_event_listener =
+ gail_util_remove_global_event_listener;
+ atk_class->add_key_event_listener =
+ gail_util_add_key_event_listener;
+ atk_class->remove_key_event_listener =
+ gail_util_remove_key_event_listener;
+ atk_class->get_root = gail_util_get_root;
+ atk_class->get_toolkit_name = gail_util_get_toolkit_name;
+ atk_class->get_toolkit_version = gail_util_get_toolkit_version;
+
+ listener_list = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
+ _listener_info_destroy);
+}
+
+static void
+gail_util_init (GailUtil *utils)
+{
+}
+
+static guint
+gail_util_add_global_event_listener (GSignalEmissionHook listener,
+ const gchar *event_type)
+{
+ guint rc = 0;
+ gchar **split_string;
+
+ split_string = g_strsplit (event_type, ":", 3);
+
+ if (split_string)
+ {
+ if (!strcmp ("window", split_string[0]))
+ {
+ static gboolean initialized = FALSE;
+
+ if (!initialized)
+ {
+ do_window_event_initialization ();
+ initialized = TRUE;
+ }
+ rc = add_listener (listener, "GailWindow", split_string[1], event_type);
+ }
+ else
+ {
+ rc = add_listener (listener, split_string[1], split_string[2], event_type);
+ }
+
+ g_strfreev (split_string);
+ }
+
+ return rc;
+}
+
+static void
+gail_util_remove_global_event_listener (guint remove_listener)
+{
+ if (remove_listener > 0)
+ {
+ GailUtilListenerInfo *listener_info;
+ gint tmp_idx = remove_listener;
+
+ listener_info = (GailUtilListenerInfo *)
+ g_hash_table_lookup(listener_list, &tmp_idx);
+
+ if (listener_info != NULL)
+ {
+ /* Hook id of 0 and signal id of 0 are invalid */
+ if (listener_info->hook_id != 0 && listener_info->signal_id != 0)
+ {
+ /* Remove the emission hook */
+ g_signal_remove_emission_hook(listener_info->signal_id,
+ listener_info->hook_id);
+
+ /* Remove the element from the hash */
+ g_hash_table_remove(listener_list, &tmp_idx);
+ }
+ else
+ {
+ g_warning("Invalid listener hook_id %ld or signal_id %d\n",
+ listener_info->hook_id, listener_info->signal_id);
+ }
+ }
+ else
+ {
+ g_warning("No listener with the specified listener id %d",
+ remove_listener);
+ }
+ }
+ else
+ {
+ g_warning("Invalid listener_id %d", remove_listener);
+ }
+}
+
+
+static
+AtkKeyEventStruct *
+atk_key_event_from_gdk_event_key (GdkEventKey *key)
+{
+ AtkKeyEventStruct *event = g_new0 (AtkKeyEventStruct, 1);
+ switch (key->type)
+ {
+ case GDK_KEY_PRESS:
+ event->type = ATK_KEY_EVENT_PRESS;
+ break;
+ case GDK_KEY_RELEASE:
+ event->type = ATK_KEY_EVENT_RELEASE;
+ break;
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+ event->state = key->state;
+ event->keyval = key->keyval;
+ event->length = key->length;
+ if (key->string && key->string [0] &&
+ (key->state & GDK_CONTROL_MASK ||
+ g_unichar_isgraph (g_utf8_get_char (key->string))))
+ {
+ event->string = key->string;
+ }
+ else if (key->type == GDK_KEY_PRESS ||
+ key->type == GDK_KEY_RELEASE)
+ {
+ event->string = gdk_keyval_name (key->keyval);
+ }
+ event->keycode = key->hardware_keycode;
+ event->timestamp = key->time;
+#ifdef GAIL_DEBUG
+ g_print ("GailKey:\tsym %u\n\tmods %x\n\tcode %u\n\ttime %lx\n",
+ (unsigned int) event->keyval,
+ (unsigned int) event->state,
+ (unsigned int) event->keycode,
+ (unsigned long int) event->timestamp);
+#endif
+ return event;
+}
+
+typedef struct {
+ AtkKeySnoopFunc func;
+ gpointer data;
+ guint key;
+} KeyEventListener;
+
+static gint
+gail_key_snooper (GtkWidget *the_widget, GdkEventKey *event, gpointer data)
+{
+ GSList *l;
+ AtkKeyEventStruct *atk_event;
+ gboolean result;
+
+ atk_event = atk_key_event_from_gdk_event_key (event);
+
+ result = FALSE;
+
+ for (l = key_listener_list; l; l = l->next)
+ {
+ KeyEventListener *listener = l->data;
+
+ result |= listener->func (atk_event, listener->data);
+ }
+ g_free (atk_event);
+
+ return result;
+}
+
+static guint
+gail_util_add_key_event_listener (AtkKeySnoopFunc listener_func,
+ gpointer listener_data)
+{
+ static guint key = 0;
+ KeyEventListener *listener;
+
+ if (key_snooper_id == 0)
+ key_snooper_id = gtk_key_snooper_install (gail_key_snooper, NULL);
+
+ key++;
+
+ listener = g_slice_new0 (KeyEventListener);
+ listener->func = listener_func;
+ listener->data = listener_data;
+ listener->key = key;
+
+ key_listener_list = g_slist_append (key_listener_list, listener);
+
+ return key;
+}
+
+static void
+gail_util_remove_key_event_listener (guint listener_key)
+{
+ GSList *l;
+
+ for (l = key_listener_list; l; l = l->next)
+ {
+ KeyEventListener *listener = l->data;
+
+ if (listener->key == listener_key)
+ {
+ g_slice_free (KeyEventListener, listener);
+ key_listener_list = g_slist_delete_link (key_listener_list, l);
+
+ break;
+ }
+ }
+
+ if (key_listener_list == NULL)
+ {
+ gtk_key_snooper_remove (key_snooper_id);
+ key_snooper_id = 0;
+ }
+}
+
+static AtkObject*
+gail_util_get_root (void)
+{
+ if (!root)
+ {
+ root = g_object_new (GAIL_TYPE_TOPLEVEL, NULL);
+ atk_object_initialize (root, NULL);
+ }
+
+ return root;
+}
+
+static const gchar *
+gail_util_get_toolkit_name (void)
+{
+ return "GAIL";
+}
+
+static const gchar *
+gail_util_get_toolkit_version (void)
+{
+ /*
+ * Version is passed in as a -D flag when this file is
+ * compiled.
+ */
+ return GTK_VERSION;
+}
+
+static void
+_listener_info_destroy (gpointer data)
+{
+ g_free(data);
+}
+
+static guint
+add_listener (GSignalEmissionHook listener,
+ const gchar *object_type,
+ const gchar *signal,
+ const gchar *hook_data)
+{
+ GType type;
+ guint signal_id;
+ gint rc = 0;
+
+ type = g_type_from_name (object_type);
+ if (type)
+ {
+ signal_id = g_signal_lookup (signal, type);
+ if (signal_id > 0)
+ {
+ GailUtilListenerInfo *listener_info;
+
+ rc = listener_idx;
+
+ listener_info = g_malloc(sizeof(GailUtilListenerInfo));
+ listener_info->key = listener_idx;
+ listener_info->hook_id =
+ g_signal_add_emission_hook (signal_id, 0, listener,
+ g_strdup (hook_data),
+ (GDestroyNotify) g_free);
+ listener_info->signal_id = signal_id;
+
+ g_hash_table_insert(listener_list, &(listener_info->key), listener_info);
+ listener_idx++;
+ }
+ else
+ {
+ g_warning("Invalid signal type %s\n", signal);
+ }
+ }
+ else
+ {
+ g_warning("Invalid object type %s\n", object_type);
+ }
+ return rc;
+}
+
+static void
+do_window_event_initialization (void)
+{
+ AtkObject *root;
+
+ /*
+ * Ensure that GailWindowClass exists.
+ */
+ g_type_class_ref (GAIL_TYPE_WINDOW);
+ g_signal_add_emission_hook (g_signal_lookup ("window-state-event", GTK_TYPE_WIDGET),
+ 0, state_event_watcher, NULL, (GDestroyNotify) NULL);
+ g_signal_add_emission_hook (g_signal_lookup ("configure-event", GTK_TYPE_WIDGET),
+ 0, configure_event_watcher, NULL, (GDestroyNotify) NULL);
+
+ root = atk_get_root ();
+ g_signal_connect (root, "children-changed::add",
+ (GCallback) window_added, NULL);
+ g_signal_connect (root, "children-changed::remove",
+ (GCallback) window_removed, NULL);
+}
+
+static gboolean
+state_event_watcher (GSignalInvocationHint *hint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+ AtkObject *atk_obj;
+ AtkObject *parent;
+ GdkEventWindowState *event;
+ gchar *signal_name;
+ guint signal_id;
+
+ object = g_value_get_object (param_values + 0);
+ /*
+ * The object can be a GtkMenu when it is popped up; we ignore this
+ */
+ if (!GTK_IS_WINDOW (object))
+ return FALSE;
+
+ event = g_value_get_boxed (param_values + 1);
+ gail_return_val_if_fail (event->type == GDK_WINDOW_STATE, FALSE);
+ widget = GTK_WIDGET (object);
+
+ if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
+ {
+ signal_name = "maximize";
+ }
+ else if (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)
+ {
+ signal_name = "minimize";
+ }
+ else if (event->new_window_state == 0)
+ {
+ signal_name = "restore";
+ }
+ else
+ return TRUE;
+
+ atk_obj = gtk_widget_get_accessible (widget);
+
+ if (GAIL_IS_WINDOW (atk_obj))
+ {
+ parent = atk_object_get_parent (atk_obj);
+ if (parent == atk_get_root ())
+ {
+ signal_id = g_signal_lookup (signal_name, GAIL_TYPE_WINDOW);
+ g_signal_emit (atk_obj, signal_id, 0);
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static void
+window_added (AtkObject *atk_obj,
+ guint index,
+ AtkObject *child)
+{
+ GtkWidget *widget;
+
+ if (!GAIL_IS_WINDOW (child)) return;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (child));
+ gail_return_if_fail (widget);
+
+ g_signal_connect (widget, "focus-in-event",
+ (GCallback) window_focus, NULL);
+ g_signal_connect (widget, "focus-out-event",
+ (GCallback) window_focus, NULL);
+ g_signal_emit (child, g_signal_lookup ("create", GAIL_TYPE_WINDOW), 0);
+}
+
+
+static void
+window_removed (AtkObject *atk_obj,
+ guint index,
+ AtkObject *child)
+{
+ GtkWidget *widget;
+ GtkWindow *window;
+
+ if (!GAIL_IS_WINDOW (child)) return;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (child));
+ gail_return_if_fail (widget);
+
+ window = GTK_WINDOW (widget);
+ /*
+ * Deactivate window if it is still focused and we are removing it. This
+ * can happen when a dialog displayed by gok is removed.
+ */
+ if (gtk_window_is_active (window) &&
+ gtk_window_has_toplevel_focus (window))
+ {
+ gchar *signal_name;
+ AtkObject *atk_obj;
+
+ atk_obj = gtk_widget_get_accessible (widget);
+ signal_name = "deactivate";
+ g_signal_emit (atk_obj, g_signal_lookup (signal_name, GAIL_TYPE_WINDOW), 0);
+ }
+
+ g_signal_handlers_disconnect_by_func (widget, (gpointer) window_focus, NULL);
+ g_signal_emit (child, g_signal_lookup ("destroy", GAIL_TYPE_WINDOW), 0);
+}
+
+static gboolean
+window_focus (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ gchar *signal_name;
+ AtkObject *atk_obj;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ atk_obj = gtk_widget_get_accessible (widget);
+ signal_name = (event->in) ? "activate" : "deactivate";
+ g_signal_emit (atk_obj, g_signal_lookup (signal_name, GAIL_TYPE_WINDOW), 0);
+
+ return FALSE;
+}
+
+static gboolean
+configure_event_watcher (GSignalInvocationHint *hint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GtkAllocation allocation;
+ GObject *object;
+ GtkWidget *widget;
+ AtkObject *atk_obj;
+ AtkObject *parent;
+ GdkEvent *event;
+ gchar *signal_name;
+ guint signal_id;
+
+ object = g_value_get_object (param_values + 0);
+ if (!GTK_IS_WINDOW (object))
+ /*
+ * GtkDrawingArea can send a GDK_CONFIGURE event but we ignore here
+ */
+ return FALSE;
+
+ event = g_value_get_boxed (param_values + 1);
+ if (event->type != GDK_CONFIGURE)
+ return FALSE;
+ widget = GTK_WIDGET (object);
+ gtk_widget_get_allocation (widget, &allocation);
+ if (allocation.x == ((GdkEventConfigure *)event)->x &&
+ allocation.y == ((GdkEventConfigure *)event)->y &&
+ allocation.width == ((GdkEventConfigure *)event)->width &&
+ allocation.height == ((GdkEventConfigure *)event)->height)
+ return TRUE;
+
+ if (allocation.width != ((GdkEventConfigure *)event)->width ||
+ allocation.height != ((GdkEventConfigure *)event)->height)
+ {
+ signal_name = "resize";
+ }
+ else
+ {
+ signal_name = "move";
+ }
+
+ atk_obj = gtk_widget_get_accessible (widget);
+ if (GAIL_IS_WINDOW (atk_obj))
+ {
+ parent = atk_object_get_parent (atk_obj);
+ if (parent == atk_get_root ())
+ {
+ signal_id = g_signal_lookup (signal_name, GAIL_TYPE_WINDOW);
+ g_signal_emit (atk_obj, signal_id, 0);
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+G_DEFINE_TYPE (GailMisc, gail_misc, ATK_TYPE_MISC)
+
+static void
+gail_misc_class_init (GailMiscClass *klass)
+{
+ AtkMiscClass *miscclass = ATK_MISC_CLASS (klass);
+ miscclass->threads_enter =
+ gail_misc_threads_enter;
+ miscclass->threads_leave =
+ gail_misc_threads_leave;
+ atk_misc_instance = g_object_new (GAIL_TYPE_MISC, NULL);
+}
+
+static void
+gail_misc_init (GailMisc *misc)
+{
+}
+
+static void gail_misc_threads_enter (AtkMisc *misc)
+{
+ GDK_THREADS_ENTER ();
+}
+
+static void gail_misc_threads_leave (AtkMisc *misc)
+{
+ GDK_THREADS_LEAVE ();
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_UTIL_H__
+#define __GAIL_UTIL_H__
+
+#include <atk/atk.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_UTIL (gail_util_get_type ())
+#define GAIL_UTIL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_UTIL, GailUtil))
+#define GAIL_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_UTIL, GailUtilClass))
+#define GAIL_IS_UTIL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_UTIL))
+#define GAIL_IS_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_UTIL))
+#define GAIL_UTIL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_UTIL, GailUtilClass))
+
+typedef struct _GailUtil GailUtil;
+typedef struct _GailUtilClass GailUtilClass;
+
+struct _GailUtil
+{
+ AtkUtil parent;
+ GList *listener_list;
+};
+
+GType gail_util_get_type (void);
+
+struct _GailUtilClass
+{
+ AtkUtilClass parent_class;
+};
+
+#define GAIL_TYPE_MISC (gail_misc_get_type ())
+#define GAIL_MISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_MISC, GailMisc))
+#define GAIL_MISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_MISC, GailMiscClass))
+#define GAIL_IS_MISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_MISC))
+#define GAIL_IS_MISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_MISC))
+#define GAIL_MISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_MISC, GailMiscClass))
+
+typedef struct _GailMisc GailMisc;
+typedef struct _GailMiscClass GailMiscClass;
+
+struct _GailMisc
+{
+ AtkMisc parent;
+};
+
+GType gail_misc_get_type (void);
+
+struct _GailMiscClass
+{
+ AtkMiscClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_UTIL_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
+#include <gdk/x11/gdkx.h>
+#endif
+#include "gailwidget.h"
+#include "gailnotebookpage.h"
+#include "gail-private-macros.h"
+
+extern GtkWidget *focus_widget;
+
+static void gail_widget_class_init (GailWidgetClass *klass);
+static void gail_widget_init (GailWidget *accessible);
+static void gail_widget_connect_widget_destroyed (GtkAccessible *accessible);
+static void gail_widget_destroyed (GtkWidget *widget,
+ GtkAccessible *accessible);
+
+static const gchar* gail_widget_get_description (AtkObject *accessible);
+static AtkObject* gail_widget_get_parent (AtkObject *accessible);
+static AtkStateSet* gail_widget_ref_state_set (AtkObject *accessible);
+static AtkRelationSet* gail_widget_ref_relation_set (AtkObject *accessible);
+static gint gail_widget_get_index_in_parent (AtkObject *accessible);
+
+static void atk_component_interface_init (AtkComponentIface *iface);
+
+static guint gail_widget_add_focus_handler
+ (AtkComponent *component,
+ AtkFocusHandler handler);
+
+static void gail_widget_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+
+static void gail_widget_get_size (AtkComponent *component,
+ gint *width,
+ gint *height);
+
+static AtkLayer gail_widget_get_layer (AtkComponent *component);
+
+static gboolean gail_widget_grab_focus (AtkComponent *component);
+
+
+static void gail_widget_remove_focus_handler
+ (AtkComponent *component,
+ guint handler_id);
+
+static gboolean gail_widget_set_extents (AtkComponent *component,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ AtkCoordType coord_type);
+
+static gboolean gail_widget_set_position (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type);
+
+static gboolean gail_widget_set_size (AtkComponent *component,
+ gint width,
+ gint height);
+
+static gint gail_widget_map_gtk (GtkWidget *widget);
+static void gail_widget_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+static void gail_widget_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+static gboolean gail_widget_focus_gtk (GtkWidget *widget,
+ GdkEventFocus *event);
+static gboolean gail_widget_real_focus_gtk (GtkWidget *widget,
+ GdkEventFocus *event);
+static void gail_widget_size_allocate_gtk (GtkWidget *widget,
+ GtkAllocation *allocation);
+
+static void gail_widget_focus_event (AtkObject *obj,
+ gboolean focus_in);
+
+static void gail_widget_real_initialize (AtkObject *obj,
+ gpointer data);
+static AtkAttributeSet *gail_widget_get_attributes(AtkObject *obj);
+static GtkWidget* gail_widget_find_viewport (GtkWidget *widget);
+static gboolean gail_widget_on_screen (GtkWidget *widget);
+static gboolean gail_widget_all_parents_visible(GtkWidget *widget);
+
+G_DEFINE_TYPE_WITH_CODE (GailWidget, gail_widget, GTK_TYPE_ACCESSIBLE,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
+
+static void
+gail_widget_class_init (GailWidgetClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GtkAccessibleClass *accessible_class = GTK_ACCESSIBLE_CLASS (klass);
+
+ klass->notify_gtk = gail_widget_real_notify_gtk;
+ klass->focus_gtk = gail_widget_real_focus_gtk;
+
+ accessible_class->connect_widget_destroyed = gail_widget_connect_widget_destroyed;
+
+ class->get_description = gail_widget_get_description;
+ class->get_parent = gail_widget_get_parent;
+ class->ref_relation_set = gail_widget_ref_relation_set;
+ class->ref_state_set = gail_widget_ref_state_set;
+ class->get_index_in_parent = gail_widget_get_index_in_parent;
+ class->initialize = gail_widget_real_initialize;
+ class->get_attributes = gail_widget_get_attributes;
+}
+
+static void
+gail_widget_init (GailWidget *accessible)
+{
+}
+
+/**
+ * This function specifies the GtkWidget for which the GailWidget was created
+ * and specifies a handler to be called when the GtkWidget is destroyed.
+ **/
+static void
+gail_widget_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkAccessible *accessible;
+ GtkWidget *widget;
+
+ g_return_if_fail (GTK_IS_WIDGET (data));
+
+ widget = GTK_WIDGET (data);
+
+ accessible = GTK_ACCESSIBLE (obj);
+ gtk_accessible_set_widget (accessible, widget);
+ gtk_accessible_connect_widget_destroyed (accessible);
+ g_signal_connect_after (widget,
+ "focus-in-event",
+ G_CALLBACK (gail_widget_focus_gtk),
+ NULL);
+ g_signal_connect_after (widget,
+ "focus-out-event",
+ G_CALLBACK (gail_widget_focus_gtk),
+ NULL);
+ g_signal_connect (widget,
+ "notify",
+ G_CALLBACK (gail_widget_notify_gtk),
+ NULL);
+ g_signal_connect (widget,
+ "size_allocate",
+ G_CALLBACK (gail_widget_size_allocate_gtk),
+ NULL);
+ atk_component_add_focus_handler (ATK_COMPONENT (accessible),
+ gail_widget_focus_event);
+ /*
+ * Add signal handlers for GTK signals required to support property changes
+ */
+ g_signal_connect (widget,
+ "map",
+ G_CALLBACK (gail_widget_map_gtk),
+ NULL);
+ g_signal_connect (widget,
+ "unmap",
+ G_CALLBACK (gail_widget_map_gtk),
+ NULL);
+ g_object_set_data (G_OBJECT (obj), "atk-component-layer",
+ GINT_TO_POINTER (ATK_LAYER_WIDGET));
+
+ obj->role = ATK_ROLE_UNKNOWN;
+}
+
+AtkObject*
+gail_widget_new (GtkWidget *widget)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+ object = g_object_new (GAIL_TYPE_WIDGET, NULL);
+
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, widget);
+
+ return accessible;
+}
+
+/*
+ * This function specifies the function to be called when the widget
+ * is destroyed
+ */
+static void
+gail_widget_connect_widget_destroyed (GtkAccessible *accessible)
+{
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget)
+ {
+ g_signal_connect_after (widget,
+ "destroy",
+ G_CALLBACK (gail_widget_destroyed),
+ accessible);
+ }
+}
+
+/*
+ * This function is called when the widget is destroyed.
+ * It sets the widget field in the GtkAccessible structure to NULL
+ * and emits a state-change signal for the state ATK_STATE_DEFUNCT
+ */
+static void
+gail_widget_destroyed (GtkWidget *widget,
+ GtkAccessible *accessible)
+{
+ gtk_accessible_set_widget (accessible, NULL);
+ atk_object_notify_state_change (ATK_OBJECT (accessible), ATK_STATE_DEFUNCT,
+ TRUE);
+}
+
+static const gchar*
+gail_widget_get_description (AtkObject *accessible)
+{
+ if (accessible->description)
+ return accessible->description;
+ else
+ {
+ GtkWidget *widget;
+
+ /* Get the tooltip from the widget */
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ /*
+ * Object is defunct
+ */
+ return NULL;
+
+ return gtk_widget_get_tooltip_text (widget);
+ }
+}
+
+static AtkObject*
+gail_widget_get_parent (AtkObject *accessible)
+{
+ AtkObject *parent;
+
+ parent = accessible->accessible_parent;
+
+ if (parent != NULL)
+ g_return_val_if_fail (ATK_IS_OBJECT (parent), NULL);
+ else
+ {
+ GtkWidget *widget, *parent_widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+ gail_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+ parent_widget = gtk_widget_get_parent (widget);
+ if (parent_widget == NULL)
+ return NULL;
+
+ /*
+ * For a widget whose parent is a GtkNoteBook, we return the
+ * accessible object corresponding the GtkNotebookPage containing
+ * the widget as the accessible parent.
+ */
+ if (GTK_IS_NOTEBOOK (parent_widget))
+ {
+ gint page_num;
+ GtkWidget *child;
+ GtkNotebook *notebook;
+
+ page_num = 0;
+ notebook = GTK_NOTEBOOK (parent_widget);
+ while (TRUE)
+ {
+ child = gtk_notebook_get_nth_page (notebook, page_num);
+ if (!child)
+ break;
+ if (child == widget)
+ {
+ parent = gtk_widget_get_accessible (parent_widget);
+ parent = atk_object_ref_accessible_child (parent, page_num);
+ g_object_unref (parent);
+ return parent;
+ }
+ page_num++;
+ }
+ }
+
+ parent = gtk_widget_get_accessible (parent_widget);
+ }
+ return parent;
+}
+
+static GtkWidget*
+find_label (GtkWidget *widget)
+{
+ GList *labels;
+ GtkWidget *label;
+ GtkWidget *temp_widget;
+
+ labels = gtk_widget_list_mnemonic_labels (widget);
+ label = NULL;
+ if (labels)
+ {
+ if (labels->data)
+ {
+ if (labels->next)
+ {
+ g_warning ("Widget (%s) has more than one label", G_OBJECT_TYPE_NAME (widget));
+
+ }
+ else
+ {
+ label = labels->data;
+ }
+ }
+ g_list_free (labels);
+ }
+
+ /*
+ * Ignore a label within a button; bug #136602
+ */
+ if (label && GTK_IS_BUTTON (widget))
+ {
+ temp_widget = label;
+ while (temp_widget)
+ {
+ if (temp_widget == widget)
+ {
+ label = NULL;
+ break;
+ }
+ temp_widget = gtk_widget_get_parent (temp_widget);
+ }
+ }
+ return label;
+}
+
+static AtkRelationSet*
+gail_widget_ref_relation_set (AtkObject *obj)
+{
+ GtkWidget *widget;
+ AtkRelationSet *relation_set;
+ GtkWidget *label;
+ AtkObject *array[1];
+ AtkRelation* relation;
+
+ gail_return_val_if_fail (GAIL_IS_WIDGET (obj), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ relation_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_relation_set (obj);
+
+ if (GTK_IS_BOX (widget))
+ /*
+ * Do not report labelled-by for a GtkBox which could be a
+ * GnomeFileEntry.
+ */
+ return relation_set;
+
+ if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABELLED_BY))
+ {
+ label = find_label (widget);
+ if (label == NULL)
+ {
+ if (GTK_IS_BUTTON (widget))
+ /*
+ * Handle the case where GnomeIconEntry is the mnemonic widget.
+ * The GtkButton which is a grandchild of the GnomeIconEntry
+ * should really be the mnemonic widget. See bug #133967.
+ */
+ {
+ GtkWidget *temp_widget;
+
+ temp_widget = gtk_widget_get_parent (widget);
+
+ if (GTK_IS_ALIGNMENT (temp_widget))
+ {
+ temp_widget = gtk_widget_get_parent (temp_widget);
+ if (GTK_IS_BOX (temp_widget))
+ {
+ label = find_label (temp_widget);
+
+ if (!label)
+ label = find_label (gtk_widget_get_parent (temp_widget));
+ }
+ }
+ }
+ else if (GTK_IS_COMBO_BOX (widget))
+ /*
+ * Handle the case when GtkFileChooserButton is the mnemonic
+ * widget. The GtkComboBox which is a child of the
+ * GtkFileChooserButton should be the mnemonic widget.
+ * See bug #359843.
+ */
+ {
+ GtkWidget *temp_widget;
+
+ temp_widget = gtk_widget_get_parent (widget);
+ if (GTK_IS_BOX (temp_widget))
+ {
+ label = find_label (temp_widget);
+ }
+ }
+ }
+
+ if (label)
+ {
+ array [0] = gtk_widget_get_accessible (label);
+
+ relation = atk_relation_new (array, 1, ATK_RELATION_LABELLED_BY);
+ atk_relation_set_add (relation_set, relation);
+ g_object_unref (relation);
+ }
+ }
+
+ return relation_set;
+}
+
+static AtkStateSet*
+gail_widget_ref_state_set (AtkObject *accessible)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ AtkStateSet *state_set;
+
+ state_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_state_set (accessible);
+
+ if (widget == NULL)
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
+ }
+ else
+ {
+ if (gtk_widget_is_sensitive (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
+ }
+
+ if (gtk_widget_get_can_focus (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
+ }
+ /*
+ * We do not currently generate notifications when an ATK object
+ * corresponding to a GtkWidget changes visibility by being scrolled
+ * on or off the screen. The testcase for this is the main window
+ * of the testgtk application in which a set of buttons in a GtkVBox
+ * is in a scrooled window with a viewport.
+ *
+ * To generate the notifications we would need to do the following:
+ * 1) Find the GtkViewPort among the antecendents of the objects
+ * 2) Create an accesible for the GtkViewPort
+ * 3) Connect to the value-changed signal on the viewport
+ * 4) When the signal is received we need to traverse the children
+ * of the viewport and check whether the children are visible or not
+ * visible; we may want to restrict this to the widgets for which
+ * accessible objects have been created.
+ * 5) We probably need to store a variable on_screen in the
+ * GailWidget data structure so we can determine whether the value has
+ * changed.
+ */
+ if (gtk_widget_get_visible (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
+ if (gail_widget_on_screen (widget) && gtk_widget_get_mapped (widget) &&
+ gail_widget_all_parents_visible (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+ }
+ }
+
+ if (gtk_widget_has_focus (widget) && (widget == focus_widget))
+ {
+ AtkObject *focus_obj;
+
+ focus_obj = g_object_get_data (G_OBJECT (accessible), "gail-focus-object");
+ if (focus_obj == NULL)
+ atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
+ }
+ if (gtk_widget_has_default (widget))
+ {
+ atk_state_set_add_state (state_set, ATK_STATE_DEFAULT);
+ }
+
+ if (GTK_IS_ORIENTABLE(widget))
+ switch (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)))
+ {
+ case GTK_ORIENTATION_HORIZONTAL:
+ atk_state_set_add_state (state_set, ATK_STATE_HORIZONTAL);
+ break;
+
+ case GTK_ORIENTATION_VERTICAL:
+ atk_state_set_add_state (state_set, ATK_STATE_VERTICAL);
+ break;
+ }
+ }
+ return state_set;
+}
+
+static gint
+gail_widget_get_index_in_parent (AtkObject *accessible)
+{
+ GtkWidget *widget;
+ GtkWidget *parent_widget;
+ gint index;
+ GList *children;
+ GType type;
+
+ type = g_type_from_name ("GailCanvasWidget");
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return -1;
+
+ if (accessible->accessible_parent)
+ {
+ AtkObject *parent;
+
+ parent = accessible->accessible_parent;
+
+ if (GAIL_IS_NOTEBOOK_PAGE (parent) ||
+ G_TYPE_CHECK_INSTANCE_TYPE ((parent), type))
+ return 0;
+ else
+ {
+ gint n_children, i;
+ gboolean found = FALSE;
+
+ n_children = atk_object_get_n_accessible_children (parent);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (parent, i);
+ if (child == accessible)
+ found = TRUE;
+
+ g_object_unref (child);
+ if (found)
+ return i;
+ }
+ }
+ }
+
+ gail_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
+ parent_widget = gtk_widget_get_parent (widget);
+ if (parent_widget == NULL)
+ return -1;
+ gail_return_val_if_fail (GTK_IS_CONTAINER (parent_widget), -1);
+
+ children = gtk_container_get_children (GTK_CONTAINER (parent_widget));
+
+ index = g_list_index (children, widget);
+ g_list_free (children);
+ return index;
+}
+
+static void
+atk_component_interface_init (AtkComponentIface *iface)
+{
+ /*
+ * Use default implementation for contains and get_position
+ */
+ iface->add_focus_handler = gail_widget_add_focus_handler;
+ iface->get_extents = gail_widget_get_extents;
+ iface->get_size = gail_widget_get_size;
+ iface->get_layer = gail_widget_get_layer;
+ iface->grab_focus = gail_widget_grab_focus;
+ iface->remove_focus_handler = gail_widget_remove_focus_handler;
+ iface->set_extents = gail_widget_set_extents;
+ iface->set_position = gail_widget_set_position;
+ iface->set_size = gail_widget_set_size;
+}
+
+static guint
+gail_widget_add_focus_handler (AtkComponent *component,
+ AtkFocusHandler handler)
+{
+ GSignalMatchType match_type;
+ gulong ret;
+ guint signal_id;
+
+ match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC;
+ signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT);
+
+ ret = g_signal_handler_find (component, match_type, signal_id, 0, NULL,
+ (gpointer) handler, NULL);
+ if (!ret)
+ {
+ return g_signal_connect_closure_by_id (component,
+ signal_id, 0,
+ g_cclosure_new (
+ G_CALLBACK (handler), NULL,
+ (GClosureNotify) NULL),
+ FALSE);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static void
+gail_widget_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ GtkAllocation allocation;
+ GdkWindow *window;
+ gint x_window, y_window;
+ gint x_toplevel, y_toplevel;
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ /*
+ * Object is defunct
+ */
+ return;
+
+ gail_return_if_fail (GTK_IS_WIDGET (widget));
+
+ gtk_widget_get_allocation (widget, &allocation);
+ *width = allocation.width;
+ *height = allocation.height;
+ if (!gail_widget_on_screen (widget) || (!gtk_widget_is_drawable (widget)))
+ {
+ *x = G_MININT;
+ *y = G_MININT;
+ return;
+ }
+
+ if (gtk_widget_get_parent (widget))
+ {
+ *x = allocation.x;
+ *y = allocation.y;
+ window = gtk_widget_get_parent_window (widget);
+ }
+ else
+ {
+ *x = 0;
+ *y = 0;
+ window = gtk_widget_get_window (widget);
+ }
+ gdk_window_get_origin (window, &x_window, &y_window);
+ *x += x_window;
+ *y += y_window;
+
+
+ if (coord_type == ATK_XY_WINDOW)
+ {
+ window = gdk_window_get_toplevel (gtk_widget_get_window (widget));
+ gdk_window_get_origin (window, &x_toplevel, &y_toplevel);
+
+ *x -= x_toplevel;
+ *y -= y_toplevel;
+ }
+}
+
+static void
+gail_widget_get_size (AtkComponent *component,
+ gint *width,
+ gint *height)
+{
+ GtkAllocation allocation;
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ /*
+ * Object is defunct
+ */
+ return;
+
+ gail_return_if_fail (GTK_IS_WIDGET (widget));
+
+ gtk_widget_get_allocation (widget, &allocation);
+ *width = allocation.width;
+ *height = allocation.height;
+}
+
+static AtkLayer
+gail_widget_get_layer (AtkComponent *component)
+{
+ gint layer;
+ layer = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (component), "atk-component-layer"));
+
+ return (AtkLayer) layer;
+}
+
+static gboolean
+gail_widget_grab_focus (AtkComponent *component)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+ GtkWidget *toplevel;
+
+ gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+ if (gtk_widget_get_can_focus (widget))
+ {
+ gtk_widget_grab_focus (widget);
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (gtk_widget_is_toplevel (toplevel))
+ {
+#ifdef GDK_WINDOWING_X11
+ gtk_window_present_with_time (GTK_WINDOW (toplevel),
+ gdk_x11_get_server_time (gtk_widget_get_window (widget)));
+#else
+ gtk_window_present (GTK_WINDOW (toplevel));
+#endif
+ }
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+gail_widget_remove_focus_handler (AtkComponent *component,
+ guint handler_id)
+{
+ g_signal_handler_disconnect (component, handler_id);
+}
+
+static gboolean
+gail_widget_set_extents (AtkComponent *component,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ AtkCoordType coord_type)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ /*
+ * Object is defunct
+ */
+ return FALSE;
+ gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ if (gtk_widget_is_toplevel (widget))
+ {
+ if (coord_type == ATK_XY_WINDOW)
+ {
+ gint x_current, y_current;
+ GdkWindow *window = gtk_widget_get_window (widget);
+
+ gdk_window_get_origin (window, &x_current, &y_current);
+ x_current += x;
+ y_current += y;
+ if (x_current < 0 || y_current < 0)
+ return FALSE;
+ else
+ {
+ gtk_window_move (GTK_WINDOW (widget), x_current, y_current);
+ gtk_widget_set_size_request (widget, width, height);
+ return TRUE;
+ }
+ }
+ else if (coord_type == ATK_XY_SCREEN)
+ {
+ gtk_window_move (GTK_WINDOW (widget), x, y);
+ gtk_widget_set_size_request (widget, width, height);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static gboolean
+gail_widget_set_position (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ /*
+ * Object is defunct
+ */
+ return FALSE;
+ gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ if (gtk_widget_is_toplevel (widget))
+ {
+ if (coord_type == ATK_XY_WINDOW)
+ {
+ gint x_current, y_current;
+ GdkWindow *window = gtk_widget_get_window (widget);
+
+ gdk_window_get_origin (window, &x_current, &y_current);
+ x_current += x;
+ y_current += y;
+ if (x_current < 0 || y_current < 0)
+ return FALSE;
+ else
+ {
+ gtk_window_move (GTK_WINDOW (widget), x_current, y_current);
+ return TRUE;
+ }
+ }
+ else if (coord_type == ATK_XY_SCREEN)
+ {
+ gtk_window_move (GTK_WINDOW (widget), x, y);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static gboolean
+gail_widget_set_size (AtkComponent *component,
+ gint width,
+ gint height)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ /*
+ * Object is defunct
+ */
+ return FALSE;
+ gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ if (gtk_widget_is_toplevel (widget))
+ {
+ gtk_widget_set_size_request (widget, width, height);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/*
+ * This function is a signal handler for notify_in_event and focus_out_event
+ * signal which gets emitted on a GtkWidget.
+ */
+static gboolean
+gail_widget_focus_gtk (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ GailWidget *gail_widget;
+ GailWidgetClass *klass;
+
+ gail_widget = GAIL_WIDGET (gtk_widget_get_accessible (widget));
+ klass = GAIL_WIDGET_GET_CLASS (gail_widget);
+ if (klass->focus_gtk)
+ return klass->focus_gtk (widget, event);
+ else
+ return FALSE;
+}
+
+/*
+ * This function is the signal handler defined for focus_in_event and
+ * focus_out_event got GailWidget.
+ *
+ * It emits a focus-event signal on the GailWidget.
+ */
+static gboolean
+gail_widget_real_focus_gtk (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ AtkObject* accessible;
+ gboolean return_val;
+ return_val = FALSE;
+
+ accessible = gtk_widget_get_accessible (widget);
+ g_signal_emit_by_name (accessible, "focus_event", event->in, &return_val);
+ return FALSE;
+}
+
+static void
+gail_widget_size_allocate_gtk (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ AtkObject* accessible;
+ AtkRectangle rect;
+
+ accessible = gtk_widget_get_accessible (widget);
+ if (ATK_IS_COMPONENT (accessible))
+ {
+ rect.x = allocation->x;
+ rect.y = allocation->y;
+ rect.width = allocation->width;
+ rect.height = allocation->height;
+ g_signal_emit_by_name (accessible, "bounds_changed", &rect);
+ }
+}
+
+/*
+ * This function is the signal handler defined for map and unmap signals.
+ */
+static gint
+gail_widget_map_gtk (GtkWidget *widget)
+{
+ AtkObject* accessible;
+
+ accessible = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (accessible, ATK_STATE_SHOWING,
+ gtk_widget_get_mapped (widget));
+ return 1;
+}
+
+/*
+ * This function is a signal handler for notify signal which gets emitted
+ * when a property changes value on the GtkWidget associated with the object.
+ *
+ * It calls a function for the GailWidget type
+ */
+static void
+gail_widget_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GailWidget *widget;
+ GailWidgetClass *klass;
+
+ widget = GAIL_WIDGET (gtk_widget_get_accessible (GTK_WIDGET (obj)));
+ klass = GAIL_WIDGET_GET_CLASS (widget);
+ if (klass->notify_gtk)
+ klass->notify_gtk (obj, pspec);
+}
+
+/*
+ * This function is a signal handler for notify signal which gets emitted
+ * when a property changes value on the GtkWidget associated with a GailWidget.
+ *
+ * It constructs an AtkPropertyValues structure and emits a "property_changed"
+ * signal which causes the user specified AtkPropertyChangeHandler
+ * to be called.
+ */
+static void
+gail_widget_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkWidget* widget = GTK_WIDGET (obj);
+ AtkObject* atk_obj = gtk_widget_get_accessible (widget);
+ AtkState state;
+ gboolean value;
+
+ if (strcmp (pspec->name, "has-focus") == 0)
+ /*
+ * We use focus-in-event and focus-out-event signals to catch
+ * focus changes so we ignore this.
+ */
+ return;
+ else if (strcmp (pspec->name, "visible") == 0)
+ {
+ state = ATK_STATE_VISIBLE;
+ value = gtk_widget_get_visible (widget);
+ }
+ else if (strcmp (pspec->name, "sensitive") == 0)
+ {
+ state = ATK_STATE_SENSITIVE;
+ value = gtk_widget_get_sensitive (widget);
+ }
+ else if (strcmp (pspec->name, "orientation") == 0)
+ {
+ GtkOrientable *orientable;
+
+ orientable = GTK_ORIENTABLE (widget);
+
+ state = ATK_STATE_HORIZONTAL;
+ value = (gtk_orientable_get_orientation (orientable) == GTK_ORIENTATION_HORIZONTAL);
+ }
+ else
+ return;
+
+ atk_object_notify_state_change (atk_obj, state, value);
+ if (state == ATK_STATE_SENSITIVE)
+ atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, value);
+
+ if (state == ATK_STATE_HORIZONTAL)
+ atk_object_notify_state_change (atk_obj, ATK_STATE_VERTICAL, !value);
+}
+
+static void
+gail_widget_focus_event (AtkObject *obj,
+ gboolean focus_in)
+{
+ AtkObject *focus_obj;
+
+ focus_obj = g_object_get_data (G_OBJECT (obj), "gail-focus-object");
+ if (focus_obj == NULL)
+ focus_obj = obj;
+ atk_object_notify_state_change (focus_obj, ATK_STATE_FOCUSED, focus_in);
+}
+
+static GtkWidget*
+gail_widget_find_viewport (GtkWidget *widget)
+{
+ /*
+ * Find an antecedent which is a GtkViewPort
+ */
+ GtkWidget *parent;
+
+ parent = gtk_widget_get_parent (widget);
+ while (parent != NULL)
+ {
+ if (GTK_IS_VIEWPORT (parent))
+ break;
+ parent = gtk_widget_get_parent (parent);
+ }
+ return parent;
+}
+
+/*
+ * This function checks whether the widget has an antecedent which is
+ * a GtkViewport and, if so, whether any part of the widget intersects
+ * the visible rectangle of the GtkViewport.
+ */
+static gboolean gail_widget_on_screen (GtkWidget *widget)
+{
+ GtkAllocation allocation;
+ GtkWidget *viewport;
+ gboolean return_value;
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ viewport = gail_widget_find_viewport (widget);
+ if (viewport)
+ {
+ GtkAllocation viewport_allocation;
+ GtkAdjustment *adjustment;
+ GdkRectangle visible_rect;
+
+ gtk_widget_get_allocation (viewport, &viewport_allocation);
+
+ adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (viewport));
+ visible_rect.y = gtk_adjustment_get_value (adjustment);
+ adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (viewport));
+ visible_rect.x = gtk_adjustment_get_value (adjustment);
+ visible_rect.width = viewport_allocation.width;
+ visible_rect.height = viewport_allocation.height;
+
+ if (((allocation.x + allocation.width) < visible_rect.x) ||
+ ((allocation.y + allocation.height) < visible_rect.y) ||
+ (allocation.x > (visible_rect.x + visible_rect.width)) ||
+ (allocation.y > (visible_rect.y + visible_rect.height)))
+ return_value = FALSE;
+ else
+ return_value = TRUE;
+ }
+ else
+ {
+ /*
+ * Check whether the widget has been placed of the screen. The
+ * widget may be MAPPED as when toolbar items do not fit on the toolbar.
+ */
+ if (allocation.x + allocation.width <= 0 &&
+ allocation.y + allocation.height <= 0)
+ return_value = FALSE;
+ else
+ return_value = TRUE;
+ }
+
+ return return_value;
+}
+
+/**
+ * gail_widget_all_parents_visible:
+ * @widget: a #GtkWidget
+ *
+ * Checks if all the predecesors (the parent widget, his parent, etc) are visible
+ * Used to check properly the SHOWING state.
+ *
+ * Return value: TRUE if all the parent hierarchy is visible, FALSE otherwise
+ **/
+static gboolean gail_widget_all_parents_visible (GtkWidget *widget)
+{
+ GtkWidget *iter_parent = NULL;
+ gboolean result = TRUE;
+
+ for (iter_parent = gtk_widget_get_parent (widget); iter_parent;
+ iter_parent = gtk_widget_get_parent (iter_parent))
+ {
+ if (!gtk_widget_get_visible (iter_parent))
+ {
+ result = FALSE;
+ break;
+ }
+ }
+
+ return result;
+}
+
+static AtkAttributeSet *gail_widget_get_attributes(AtkObject *obj)
+{
+ AtkAttributeSet *attributes;
+ AtkAttribute *toolkit = g_malloc(sizeof(AtkAttribute));
+
+ toolkit->name = g_strdup("toolkit");
+ toolkit->value = g_strdup("gail");
+
+ attributes = g_slist_append(NULL, toolkit);
+
+ return attributes;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_WIDGET_H__
+#define __GAIL_WIDGET_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_WIDGET (gail_widget_get_type ())
+#define GAIL_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_WIDGET, GailWidget))
+#define GAIL_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_WIDGET, GailWidgetClass))
+#define GAIL_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_WIDGET))
+#define GAIL_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_WIDGET))
+#define GAIL_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_WIDGET, GailWidgetClass))
+
+typedef struct _GailWidget GailWidget;
+typedef struct _GailWidgetClass GailWidgetClass;
+
+struct _GailWidget
+{
+ GtkAccessible parent;
+};
+
+GType gail_widget_get_type (void);
+
+struct _GailWidgetClass
+{
+ GtkAccessibleClass parent_class;
+
+ /*
+ * Signal handler for notify signal on GTK widget
+ */
+ void (*notify_gtk) (GObject *object,
+ GParamSpec *pspec);
+ /*
+ * Signal handler for focus_in_event and focus_out_event signal on GTK widget
+ */
+ gboolean (*focus_gtk) (GtkWidget *widget,
+ GdkEventFocus *event);
+
+};
+
+AtkObject* gail_widget_new (GtkWidget *widget);
+
+G_END_DECLS
+
+#endif /* __GAIL_WIDGET_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gtk/gtkx.h>
+
+#include "gailwindow.h"
+#include "gailtoplevel.h"
+#include "gail-private-macros.h"
+
+enum {
+ ACTIVATE,
+ CREATE,
+ DEACTIVATE,
+ DESTROY,
+ MAXIMIZE,
+ MINIMIZE,
+ MOVE,
+ RESIZE,
+ RESTORE,
+ LAST_SIGNAL
+};
+
+static void gail_window_class_init (GailWindowClass *klass);
+
+static void gail_window_init (GailWindow *accessible);
+
+static void gail_window_real_initialize (AtkObject *obj,
+ gpointer data);
+static void gail_window_finalize (GObject *object);
+
+static const gchar* gail_window_get_name (AtkObject *accessible);
+
+static AtkObject* gail_window_get_parent (AtkObject *accessible);
+static gint gail_window_get_index_in_parent (AtkObject *accessible);
+static gboolean gail_window_real_focus_gtk (GtkWidget *widget,
+ GdkEventFocus *event);
+
+static AtkStateSet* gail_window_ref_state_set (AtkObject *accessible);
+static AtkRelationSet* gail_window_ref_relation_set (AtkObject *accessible);
+static void gail_window_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec);
+static gint gail_window_get_mdi_zorder (AtkComponent *component);
+
+static gboolean gail_window_state_event_gtk (GtkWidget *widget,
+ GdkEventWindowState *event);
+
+/* atkcomponent.h */
+static void atk_component_interface_init (AtkComponentIface *iface);
+
+static void gail_window_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type);
+static void gail_window_get_size (AtkComponent *component,
+ gint *width,
+ gint *height);
+
+static guint gail_window_signals [LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE_WITH_CODE (GailWindow, gail_window, GAIL_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
+
+static void
+gail_window_class_init (GailWindowClass *klass)
+{
+ GailWidgetClass *widget_class;
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = gail_window_finalize;
+
+ widget_class = (GailWidgetClass*)klass;
+ widget_class->focus_gtk = gail_window_real_focus_gtk;
+ widget_class->notify_gtk = gail_window_real_notify_gtk;
+
+ class->get_name = gail_window_get_name;
+ class->get_parent = gail_window_get_parent;
+ class->get_index_in_parent = gail_window_get_index_in_parent;
+ class->ref_relation_set = gail_window_ref_relation_set;
+ class->ref_state_set = gail_window_ref_state_set;
+ class->initialize = gail_window_real_initialize;
+
+ gail_window_signals [ACTIVATE] =
+ g_signal_new ("activate",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* default signal handler */
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gail_window_signals [CREATE] =
+ g_signal_new ("create",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* default signal handler */
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gail_window_signals [DEACTIVATE] =
+ g_signal_new ("deactivate",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* default signal handler */
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gail_window_signals [DESTROY] =
+ g_signal_new ("destroy",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* default signal handler */
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gail_window_signals [MAXIMIZE] =
+ g_signal_new ("maximize",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* default signal handler */
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gail_window_signals [MINIMIZE] =
+ g_signal_new ("minimize",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* default signal handler */
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gail_window_signals [MOVE] =
+ g_signal_new ("move",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* default signal handler */
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gail_window_signals [RESIZE] =
+ g_signal_new ("resize",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* default signal handler */
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ gail_window_signals [RESTORE] =
+ g_signal_new ("restore",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* default signal handler */
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+gail_window_init (GailWindow *accessible)
+{
+}
+
+static void
+gail_window_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ GtkWidget *widget = GTK_WIDGET (data);
+ GailWindow *window;
+
+ /*
+ * A GailWindow can be created for a GtkHandleBox or a GtkWindow
+ */
+ if (!GTK_IS_WINDOW (widget) &&
+ !GTK_IS_HANDLE_BOX (widget))
+ gail_return_if_fail (FALSE);
+
+ ATK_OBJECT_CLASS (gail_window_parent_class)->initialize (obj, data);
+
+ window = GAIL_WINDOW (obj);
+ window->name_change_handler = 0;
+ window->previous_name = g_strdup (gtk_window_get_title (GTK_WINDOW (data)));
+
+ g_signal_connect (data,
+ "window_state_event",
+ G_CALLBACK (gail_window_state_event_gtk),
+ NULL);
+ g_object_set_data (G_OBJECT (obj), "atk-component-layer",
+ GINT_TO_POINTER (ATK_LAYER_WINDOW));
+
+ if (GTK_IS_FILE_CHOOSER_DIALOG (widget))
+ obj->role = ATK_ROLE_FILE_CHOOSER;
+ else if (GTK_IS_COLOR_SELECTION_DIALOG (widget))
+ obj->role = ATK_ROLE_COLOR_CHOOSER;
+ else if (GTK_IS_FONT_SELECTION_DIALOG (widget))
+ obj->role = ATK_ROLE_FONT_CHOOSER;
+ else if (GTK_IS_MESSAGE_DIALOG (widget))
+ obj->role = ATK_ROLE_ALERT;
+ else if (GTK_IS_DIALOG (widget))
+ obj->role = ATK_ROLE_DIALOG;
+ else
+ {
+ const gchar *name;
+
+ name = gtk_widget_get_name (widget);
+
+ if (!g_strcmp0 (name, "gtk-tooltip"))
+ obj->role = ATK_ROLE_TOOL_TIP;
+#ifdef GDK_WINDOWING_X11
+ else if (GTK_IS_PLUG (widget))
+ obj->role = ATK_ROLE_PANEL;
+#endif
+ else if (gtk_window_get_window_type (GTK_WINDOW (widget)) == GTK_WINDOW_POPUP)
+ obj->role = ATK_ROLE_WINDOW;
+ else
+ obj->role = ATK_ROLE_FRAME;
+ }
+
+ /*
+ * Notify that tooltip is showing
+ */
+ if (obj->role == ATK_ROLE_TOOL_TIP &&
+ gtk_widget_get_mapped (widget))
+ atk_object_notify_state_change (obj, ATK_STATE_SHOWING, 1);
+}
+
+static void
+gail_window_finalize (GObject *object)
+{
+ GailWindow* window = GAIL_WINDOW (object);
+
+ if (window->name_change_handler)
+ {
+ g_source_remove (window->name_change_handler);
+ window->name_change_handler = 0;
+ }
+ if (window->previous_name)
+ {
+ g_free (window->previous_name);
+ window->previous_name = NULL;
+ }
+
+ G_OBJECT_CLASS (gail_window_parent_class)->finalize (object);
+}
+
+static const gchar*
+gail_window_get_name (AtkObject *accessible)
+{
+ const gchar* name;
+
+ name = ATK_OBJECT_CLASS (gail_window_parent_class)->get_name (accessible);
+ if (name == NULL)
+ {
+ /*
+ * Get the window title if it exists
+ */
+ GtkWidget* widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ gail_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+ if (GTK_IS_WINDOW (widget))
+ {
+ GtkWindow *window = GTK_WINDOW (widget);
+
+ name = gtk_window_get_title (window);
+ if (name == NULL &&
+ accessible->role == ATK_ROLE_TOOL_TIP)
+ {
+ GtkWidget *child;
+
+ child = gtk_bin_get_child (GTK_BIN (window));
+ /* could be some kind of egg notification bubble thingy? */
+
+ /* Handle new GTK+ GNOME 2.20 tooltips */
+ if (GTK_IS_ALIGNMENT(child))
+ {
+ child = gtk_bin_get_child (GTK_BIN (child));
+ if (GTK_IS_BOX(child))
+ {
+ GList *children;
+ guint count;
+ children = gtk_container_get_children (GTK_CONTAINER (child));
+ count = g_list_length (children);
+ if (count == 2)
+ {
+ child = (GtkWidget *) g_list_nth_data (children, 1);
+ }
+ g_list_free (children);
+ }
+ }
+
+ if (!GTK_IS_LABEL (child))
+ {
+ g_message ("ATK_ROLE_TOOLTIP object found, but doesn't look like a tooltip.");
+ return NULL;
+ }
+ name = gtk_label_get_text (GTK_LABEL (child));
+ }
+ }
+ }
+ return name;
+}
+
+static AtkObject*
+gail_window_get_parent (AtkObject *accessible)
+{
+ AtkObject* parent;
+
+ parent = ATK_OBJECT_CLASS (gail_window_parent_class)->get_parent (accessible);
+
+ return parent;
+}
+
+static gint
+gail_window_get_index_in_parent (AtkObject *accessible)
+{
+ GtkWidget* widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+ AtkObject* atk_obj = atk_get_root ();
+ gint index = -1;
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return -1;
+
+ gail_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
+
+ index = ATK_OBJECT_CLASS (gail_window_parent_class)->get_index_in_parent (accessible);
+ if (index != -1)
+ return index;
+
+ if (GTK_IS_WINDOW (widget))
+ {
+ GtkWindow *window = GTK_WINDOW (widget);
+ if (GAIL_IS_TOPLEVEL (atk_obj))
+ {
+ GailToplevel* toplevel = GAIL_TOPLEVEL (atk_obj);
+ index = g_list_index (toplevel->window_list, window);
+ }
+ else
+ {
+ int i, sibling_count = atk_object_get_n_accessible_children (atk_obj);
+ for (i = 0; i < sibling_count && index == -1; ++i)
+ {
+ AtkObject *child = atk_object_ref_accessible_child (atk_obj, i);
+ if (accessible == child) index = i;
+ g_object_unref (G_OBJECT (child));
+ }
+ }
+ }
+ return index;
+}
+
+static gboolean
+gail_window_real_focus_gtk (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ AtkObject* obj;
+
+ obj = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (obj, ATK_STATE_ACTIVE, event->in);
+
+ return FALSE;
+}
+
+static AtkRelationSet*
+gail_window_ref_relation_set (AtkObject *obj)
+{
+ GtkWidget *widget;
+ AtkRelationSet *relation_set;
+ AtkObject *array[1];
+ AtkRelation* relation;
+ GtkWidget *current_widget;
+
+ gail_return_val_if_fail (GAIL_IS_WIDGET (obj), NULL);
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return NULL;
+
+ relation_set = ATK_OBJECT_CLASS (gail_window_parent_class)->ref_relation_set (obj);
+
+ if (atk_object_get_role (obj) == ATK_ROLE_TOOL_TIP)
+ {
+ relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_POPUP_FOR);
+
+ if (relation)
+ {
+ atk_relation_set_remove (relation_set, relation);
+ }
+ if (gtk_widget_get_visible(widget) && FALSE /* FIXME gtk_tooltips_get_info_from_tip_window (GTK_WINDOW (widget), NULL, ¤t_widget) */)
+ {
+ array [0] = gtk_widget_get_accessible (current_widget);
+
+ relation = atk_relation_new (array, 1, ATK_RELATION_POPUP_FOR);
+ atk_relation_set_add (relation_set, relation);
+ g_object_unref (relation);
+ }
+ }
+ return relation_set;
+}
+
+static AtkStateSet*
+gail_window_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GtkWidget *widget;
+ GtkWindow *window;
+ GdkWindow *gdk_window;
+ GdkWindowState state;
+
+ state_set = ATK_OBJECT_CLASS (gail_window_parent_class)->ref_state_set (accessible);
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
+
+ if (widget == NULL)
+ return state_set;
+
+ window = GTK_WINDOW (widget);
+
+ if (gtk_window_has_toplevel_focus (window) && gtk_window_is_active (window))
+ atk_state_set_add_state (state_set, ATK_STATE_ACTIVE);
+
+ gdk_window = gtk_widget_get_window (widget);
+ if (window)
+ {
+ state = gdk_window_get_state (gdk_window);
+ if (state & GDK_WINDOW_STATE_ICONIFIED)
+ atk_state_set_add_state (state_set, ATK_STATE_ICONIFIED);
+ }
+ if (gtk_window_get_modal (window))
+ atk_state_set_add_state (state_set, ATK_STATE_MODAL);
+
+ if (gtk_window_get_resizable (window))
+ atk_state_set_add_state (state_set, ATK_STATE_RESIZABLE);
+
+ return state_set;
+}
+
+static gboolean
+idle_notify_name_change (gpointer data)
+{
+ GailWindow *window;
+ AtkObject *obj;
+
+ window = GAIL_WINDOW (data);
+ window->name_change_handler = 0;
+ if (gtk_accessible_get_widget (GTK_ACCESSIBLE (window)) == NULL)
+ return FALSE;
+
+ obj = ATK_OBJECT (window);
+ if (obj->name == NULL)
+ {
+ /*
+ * The title has changed so notify a change in accessible-name
+ */
+ g_object_notify (G_OBJECT (obj), "accessible-name");
+ }
+ g_signal_emit_by_name (obj, "visible_data_changed");
+
+ return FALSE;
+}
+
+static void
+gail_window_real_notify_gtk (GObject *obj,
+ GParamSpec *pspec)
+{
+ GtkWidget *widget = GTK_WIDGET (obj);
+ AtkObject* atk_obj = gtk_widget_get_accessible (widget);
+ GailWindow *window = GAIL_WINDOW (atk_obj);
+ const gchar *name;
+ gboolean name_changed = FALSE;
+
+ if (strcmp (pspec->name, "title") == 0)
+ {
+ name = gtk_window_get_title (GTK_WINDOW (widget));
+ if (name)
+ {
+ if (window->previous_name == NULL ||
+ strcmp (name, window->previous_name) != 0)
+ name_changed = TRUE;
+ }
+ else if (window->previous_name != NULL)
+ name_changed = TRUE;
+
+ if (name_changed)
+ {
+ g_free (window->previous_name);
+ window->previous_name = g_strdup (name);
+
+ if (window->name_change_handler == 0)
+ window->name_change_handler = gdk_threads_add_idle (idle_notify_name_change, atk_obj);
+ }
+ }
+ else
+ GAIL_WIDGET_CLASS (gail_window_parent_class)->notify_gtk (obj, pspec);
+}
+
+static gboolean
+gail_window_state_event_gtk (GtkWidget *widget,
+ GdkEventWindowState *event)
+{
+ AtkObject* obj;
+
+ obj = gtk_widget_get_accessible (widget);
+ atk_object_notify_state_change (obj, ATK_STATE_ICONIFIED,
+ (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0);
+ return FALSE;
+}
+
+static void
+atk_component_interface_init (AtkComponentIface *iface)
+{
+ iface->get_extents = gail_window_get_extents;
+ iface->get_size = gail_window_get_size;
+ iface->get_mdi_zorder = gail_window_get_mdi_zorder;
+}
+
+static void
+gail_window_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+ GdkRectangle rect;
+ gint x_toplevel, y_toplevel;
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return;
+
+ gail_return_if_fail (GTK_IS_WINDOW (widget));
+
+ if (!gtk_widget_is_toplevel (widget))
+ {
+ AtkComponentIface *parent_iface;
+
+ parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
+ parent_iface->get_extents (component, x, y, width, height, coord_type);
+ return;
+ }
+
+ gdk_window_get_frame_extents (gtk_widget_get_window (widget),
+ &rect);
+
+ *width = rect.width;
+ *height = rect.height;
+ if (!gtk_widget_is_drawable (widget))
+ {
+ *x = G_MININT;
+ *y = G_MININT;
+ return;
+ }
+ *x = rect.x;
+ *y = rect.y;
+ if (coord_type == ATK_XY_WINDOW)
+ {
+ gdk_window_get_origin (gtk_widget_get_window (widget),
+ &x_toplevel, &y_toplevel);
+ *x -= x_toplevel;
+ *y -= y_toplevel;
+ }
+}
+
+static void
+gail_window_get_size (AtkComponent *component,
+ gint *width,
+ gint *height)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+ GdkRectangle rect;
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return;
+
+ gail_return_if_fail (GTK_IS_WINDOW (widget));
+
+ if (!gtk_widget_is_toplevel (widget))
+ {
+ AtkComponentIface *parent_iface;
+
+ parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
+ parent_iface->get_size (component, width, height);
+ return;
+ }
+ gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
+
+ *width = rect.width;
+ *height = rect.height;
+}
+
+#if defined (GDK_WINDOWING_X11)
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <gdk/x11/gdkx.h>
+
+/* _NET_CLIENT_LIST_STACKING monitoring */
+
+typedef struct {
+ Window *stacked_windows;
+ int stacked_windows_len;
+ GdkWindow *root_window;
+ guint update_handler;
+ int *desktop;
+ guint update_desktop_handler;
+ gboolean *desktop_changed;
+
+ guint screen_initialized : 1;
+ guint update_stacked_windows : 1;
+} GailScreenInfo;
+
+static GailScreenInfo *gail_screens = NULL;
+static int num_screens = 0;
+static Atom _net_client_list_stacking = None;
+static Atom _net_wm_desktop = None;
+
+static gint
+get_window_desktop (Window window)
+{
+ Atom ret_type;
+ int format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *cardinals;
+ int error;
+ int result;
+ int desktop;
+
+ if (_net_wm_desktop == None)
+ _net_wm_desktop =
+ XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_WM_DESKTOP", False);
+
+ gdk_error_trap_push ();
+ result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), window, _net_wm_desktop,
+ 0, G_MAXLONG,
+ False, XA_CARDINAL,
+ &ret_type, &format, &nitems,
+ &bytes_after, &cardinals);
+ error = gdk_error_trap_pop();
+ /* nitems < 1 will occur if the property is not set */
+ if (error != Success || result != Success || nitems < 1)
+ return -1;
+
+ desktop = *cardinals;
+
+ XFree (cardinals);
+ if (nitems != 1)
+ return -1;
+ return desktop;
+}
+
+static void
+free_screen_info (GailScreenInfo *info)
+{
+ if (info->stacked_windows)
+ XFree (info->stacked_windows);
+ if (info->desktop)
+ g_free (info->desktop);
+ if (info->desktop_changed)
+ g_free (info->desktop_changed);
+
+ info->stacked_windows = NULL;
+ info->stacked_windows_len = 0;
+ info->desktop = NULL;
+ info->desktop_changed = NULL;
+}
+
+static gboolean
+get_stacked_windows (GailScreenInfo *info)
+{
+ Atom ret_type;
+ int format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *data;
+ int error;
+ int result;
+ int i;
+ int j;
+ int *desktops;
+ gboolean *desktops_changed;
+
+ if (_net_client_list_stacking == None)
+ _net_client_list_stacking =
+ XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_CLIENT_LIST_STACKING", False);
+
+ gdk_error_trap_push ();
+ ret_type = None;
+ result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+ GDK_WINDOW_XID (info->root_window),
+ _net_client_list_stacking,
+ 0, G_MAXLONG,
+ False, XA_WINDOW, &ret_type, &format, &nitems,
+ &bytes_after, &data);
+ error = gdk_error_trap_pop ();
+ /* nitems < 1 will occur if the property is not set */
+ if (error != Success || result != Success || nitems < 1)
+ {
+ free_screen_info (info);
+ return FALSE;
+ }
+
+ if (ret_type != XA_WINDOW)
+ {
+ XFree (data);
+ free_screen_info (info);
+ return FALSE;
+ }
+
+ desktops = g_malloc0 (nitems * sizeof (int));
+ desktops_changed = g_malloc0 (nitems * sizeof (gboolean));
+ for (i = 0; i < nitems; i++)
+ {
+ gboolean window_found = FALSE;
+
+ for (j = 0; j < info->stacked_windows_len; j++)
+ {
+ if (info->stacked_windows [j] == data [i])
+ {
+ desktops [i] = info->desktop [j];
+ desktops_changed [i] = info->desktop_changed [j];
+ window_found = TRUE;
+ break;
+ }
+ }
+ if (!window_found)
+ {
+ desktops [i] = get_window_desktop (data [i]);
+ desktops_changed [i] = FALSE;
+ }
+ }
+ free_screen_info (info);
+ info->stacked_windows = (Window*) data;
+ info->stacked_windows_len = nitems;
+ info->desktop = desktops;
+ info->desktop_changed = desktops_changed;
+
+ return TRUE;
+}
+
+static gboolean
+update_screen_info (gpointer data)
+{
+ int screen_n = GPOINTER_TO_INT (data);
+
+ gail_screens [screen_n].update_handler = 0;
+ gail_screens [screen_n].update_stacked_windows = FALSE;
+
+ get_stacked_windows (&gail_screens [screen_n]);
+
+ return FALSE;
+}
+
+static gboolean
+update_desktop_info (gpointer data)
+{
+ int screen_n = GPOINTER_TO_INT (data);
+ GailScreenInfo *info;
+ int i;
+
+ info = &gail_screens [screen_n];
+ info->update_desktop_handler = 0;
+
+ for (i = 0; i < info->stacked_windows_len; i++)
+ {
+ if (info->desktop_changed [i])
+ {
+ info->desktop [i] = get_window_desktop (info->stacked_windows [i]);
+ info->desktop_changed [i] = FALSE;
+ }
+ }
+
+ return FALSE;
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdkxevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ XEvent *xevent = gdkxevent;
+
+ if (xevent->type == PropertyNotify)
+ {
+ if (xevent->xproperty.atom == _net_client_list_stacking)
+ {
+ int screen_n;
+ GdkWindow *window;
+
+ window = event->any.window;
+
+ if (window)
+ {
+ screen_n = gdk_screen_get_number (gdk_window_get_screen (window));
+
+ gail_screens [screen_n].update_stacked_windows = TRUE;
+ if (!gail_screens [screen_n].update_handler)
+ {
+ gail_screens [screen_n].update_handler = gdk_threads_add_idle (update_screen_info,
+ GINT_TO_POINTER (screen_n));
+ }
+ }
+ }
+ else if (xevent->xproperty.atom == _net_wm_desktop)
+ {
+ int i;
+ int j;
+ GailScreenInfo *info;
+
+ for (i = 0; i < num_screens; i++)
+ {
+ info = &gail_screens [i];
+ for (j = 0; j < info->stacked_windows_len; j++)
+ {
+ if (xevent->xany.window == info->stacked_windows [j])
+ {
+ info->desktop_changed [j] = TRUE;
+ if (!info->update_desktop_handler)
+ {
+ info->update_desktop_handler = gdk_threads_add_idle (update_desktop_info,
+ GINT_TO_POINTER (i));
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+display_closed (GdkDisplay *display,
+ gboolean is_error)
+{
+ int i;
+
+ for (i = 0; i < num_screens; i++)
+ {
+ if (gail_screens [i].update_handler)
+ {
+ g_source_remove (gail_screens [i].update_handler);
+ gail_screens [i].update_handler = 0;
+ }
+
+ if (gail_screens [i].update_desktop_handler)
+ {
+ g_source_remove (gail_screens [i].update_desktop_handler);
+ gail_screens [i].update_desktop_handler = 0;
+ }
+
+ free_screen_info (&gail_screens [i]);
+ }
+
+ g_free (gail_screens);
+ gail_screens = NULL;
+ num_screens = 0;
+}
+
+static void
+init_gail_screens (void)
+{
+ GdkDisplay *display;
+
+ display = gdk_display_get_default ();
+
+ num_screens = gdk_display_get_n_screens (display);
+
+ gail_screens = g_new0 (GailScreenInfo, num_screens);
+ gdk_window_add_filter (NULL, filter_func, NULL);
+
+ g_signal_connect (display, "closed", G_CALLBACK (display_closed), NULL);
+}
+
+static void
+init_gail_screen (GdkScreen *screen,
+ int screen_n)
+{
+ XWindowAttributes attrs;
+
+ gail_screens [screen_n].root_window = gdk_screen_get_root_window (screen);
+
+ get_stacked_windows (&gail_screens [screen_n]);
+
+ XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+ GDK_WINDOW_XID (gail_screens [screen_n].root_window),
+ &attrs);
+
+ XSelectInput (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+ GDK_WINDOW_XID (gail_screens [screen_n].root_window),
+ attrs.your_event_mask | PropertyChangeMask);
+
+ gail_screens [screen_n].screen_initialized = TRUE;
+}
+
+static GailScreenInfo *
+get_screen_info (GdkScreen *screen)
+{
+ int screen_n;
+
+ gail_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ screen_n = gdk_screen_get_number (screen);
+
+ if (gail_screens && gail_screens [screen_n].screen_initialized)
+ return &gail_screens [screen_n];
+
+ if (!gail_screens)
+ init_gail_screens ();
+
+ g_assert (gail_screens != NULL);
+
+ init_gail_screen (screen, screen_n);
+
+ g_assert (gail_screens [screen_n].screen_initialized);
+
+ return &gail_screens [screen_n];
+}
+
+static gint
+get_window_zorder (GdkWindow *window)
+{
+ GailScreenInfo *info;
+ Window xid;
+ int i;
+ int zorder;
+ int w_desktop;
+
+ gail_return_val_if_fail (GDK_IS_WINDOW (window), -1);
+
+ info = get_screen_info (gdk_window_get_screen (window));
+
+ gail_return_val_if_fail (info->stacked_windows != NULL, -1);
+
+ xid = GDK_WINDOW_XID (window);
+
+ w_desktop = -1;
+ for (i = 0; i < info->stacked_windows_len; i++)
+ {
+ if (info->stacked_windows [i] == xid)
+ {
+ w_desktop = info->desktop[i];
+ break;
+ }
+ }
+ if (w_desktop < 0)
+ return w_desktop;
+
+ zorder = 0;
+ for (i = 0; i < info->stacked_windows_len; i++)
+ {
+ if (info->stacked_windows [i] == xid)
+ {
+ return zorder;
+ }
+ else
+ {
+ if (info->desktop[i] == w_desktop)
+ zorder++;
+ }
+ }
+
+ return -1;
+}
+
+static gint
+gail_window_get_mdi_zorder (AtkComponent *component)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return -1;
+
+ gail_return_val_if_fail (GTK_IS_WINDOW (widget), -1);
+
+ return get_window_zorder (gtk_widget_get_window (widget));
+}
+
+#elif defined (GDK_WINDOWING_WIN32)
+
+static gint
+gail_window_get_mdi_zorder (AtkComponent *component)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return -1;
+
+ gail_return_val_if_fail (GTK_IS_WINDOW (widget), -1);
+
+ return 0; /* Punt, FIXME */
+}
+
+#else
+
+static gint
+gail_window_get_mdi_zorder (AtkComponent *component)
+{
+ GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
+
+ if (widget == NULL)
+ /*
+ * State is defunct
+ */
+ return -1;
+
+ gail_return_val_if_fail (GTK_IS_WINDOW (widget), -1);
+
+ return 0; /* Punt, FIXME */
+}
+
+#endif
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_WINDOW_H__
+#define __GAIL_WINDOW_H__
+
+#include "gailcontainer.h"
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_WINDOW (gail_window_get_type ())
+#define GAIL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_WINDOW, GailWindow))
+#define GAIL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_WINDOW, GailWindowClass))
+#define GAIL_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_WINDOW))
+#define GAIL_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_WINDOW))
+#define GAIL_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_WINDOW, GailWindowClass))
+
+typedef struct _GailWindow GailWindow;
+typedef struct _GailWindowClass GailWindowClass;
+
+struct _GailWindow
+{
+ GailContainer parent;
+
+ guint name_change_handler;
+ gchar *previous_name;
+};
+
+GType gail_window_get_type (void);
+
+struct _GailWindowClass
+{
+ GailContainerClass parent_class;
+};
+
+G_END_DECLS
+
+#endif /* __GAIL_WINDOW_H__ */
--- /dev/null
+include $(top_srcdir)/Makefile.decl
+
+EXTRA_DIST += gailutil.def
+if PLATFORM_WIN32
+no_undefined = -no-undefined
+endif
+if OS_WIN32
+export_symbols = -export-symbols $(srcdir)/gailutil.def
+install-def-file: gailutil.def
+ $(INSTALL) $(srcdir)/gailutil.def $(DESTDIR)$(libdir)
+uninstall-def-file:
+ -rm $(DESTDIR)$(libdir)/gailutil.def
+else
+install-def-file:
+uninstall-def-file:
+endif
+
+if MS_LIB_AVAILABLE
+noinst_DATA = gailutil.lib
+
+install-ms-lib:
+ $(INSTALL) gailutil.lib $(DESTDIR)$(libdir)
+
+uninstall-ms-lib:
+ -rm $(DESTDIR)$(libdir)/gailutil.lib
+else
+install-ms-lib:
+uninstall-ms-lib:
+endif
+
+
+lib_LTLIBRARIES = libgailutil-3.la
+
+util_c_sources = \
+ gailmisc.c \
+ gailtextutil.c
+
+libgailutilincludedir=$(includedir)/gail-3.0/libgail-util
+
+util_public_h_sources = \
+ gailmisc.h \
+ gailtextutil.h \
+ gail-util.h
+
+libgailutil_3_la_SOURCES = \
+ $(util_c_sources)
+
+libgailutilinclude_HEADERS = \
+ $(util_public_h_sources)
+
+libgailutil_3_la_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/gdk \
+ -I$(top_builddir)/gdk \
+ -I$(top_srcdir)/gtk \
+ -I$(top_builddir)/gtk \
+ $(AM_CPPFLAGS) \
+ -DGDK_DISABLE_DEPRECATED\
+ -DGTK_DISABLE_DEPRECATED
+
+libgailutil_3_la_CFLAGS = \
+ $(GTK_DEP_CFLAGS) \
+ $(GTK_DEBUG_FLAGS) \
+ $(AM_CFLAGS)
+
+libgailutil_3_la_LIBADD = \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS)
+
+libgailutil_3_la_LDFLAGS = \
+ -version-info $(GAIL_LT_VERSION_INFO) \
+ $(no_undefined) \
+ $(export_symbols) \
+ $(LDFLAGS)
+
+gailutil.lib: libgailutil-3.la gailutil.def
+ lib -machine:@LIB_EXE_MACHINE_FLAG@ -name:libgailutil-3.0-$(GAIL_LT_CURRENT_MINUS_AGE).dll -def:gailutil.def -out:$@
+
+install-data-local: install-ms-lib install-def-file
+
+uninstall-local: uninstall-ms-lib uninstall-def-file
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+#include <libgail-util/gailmisc.h>
+#include <libgail-util/gailtextutil.h>
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include "gailmisc.h"
+
+/* IMPORTANT!!! This source file does NOT contain the implementation
+ * code for AtkUtil - for that code, please see gail/gail.c.
+ */
+
+/**
+ * SECTION:gailmisc
+ * @Short_description: GailMisc is a set of utility functions which may be
+ * useful to implementors of Atk interfaces for custom widgets.
+ * @Title: GailMisc
+ *
+ * GailMisc is a set of utility function which are used in the implemementation
+ * of Atk interfaces for GTK+ widgets. They may be useful to implementors of
+ * Atk interfaces for custom widgets.
+ */
+
+
+/**
+ * gail_misc_get_extents_from_pango_rectangle:
+ * @widget: The widget that contains the PangoLayout, that contains
+ * the PangoRectangle
+ * @char_rect: The #PangoRectangle from which to calculate extents
+ * @x_layout: The x-offset at which the widget displays the
+ * PangoLayout that contains the PangoRectangle, relative to @widget
+ * @y_layout: The y-offset at which the widget displays the
+ * PangoLayout that contains the PangoRectangle, relative to @widget
+ * @x: The x-position of the #PangoRectangle relative to @coords
+ * @y: The y-position of the #PangoRectangle relative to @coords
+ * @width: The width of the #PangoRectangle
+ * @height: The height of the #PangoRectangle
+ * @coords: An #AtkCoordType enumeration
+ *
+ * Gets the extents of @char_rect in device coordinates,
+ * relative to either top-level window or screen coordinates as
+ * specified by @coords.
+ **/
+void
+gail_misc_get_extents_from_pango_rectangle (GtkWidget *widget,
+ PangoRectangle *char_rect,
+ gint x_layout,
+ gint y_layout,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ gint x_window, y_window, x_toplevel, y_toplevel;
+
+ gail_misc_get_origins (widget, &x_window, &y_window,
+ &x_toplevel, &y_toplevel);
+
+ *x = (char_rect->x / PANGO_SCALE) + x_layout + x_window;
+ *y = (char_rect->y / PANGO_SCALE) + y_layout + y_window;
+ if (coords == ATK_XY_WINDOW)
+ {
+ *x -= x_toplevel;
+ *y -= y_toplevel;
+ }
+ else if (coords != ATK_XY_SCREEN)
+ {
+ *x = 0;
+ *y = 0;
+ *height = 0;
+ *width = 0;
+ return;
+ }
+ *height = char_rect->height / PANGO_SCALE;
+ *width = char_rect->width / PANGO_SCALE;
+
+ return;
+}
+
+/**
+ * gail_misc_get_index_at_point_in_layout:
+ * @widget: A #GtkWidget
+ * @layout: The #PangoLayout from which to get the index at the
+ * specified point.
+ * @x_layout: The x-offset at which the widget displays the
+ * #PangoLayout, relative to @widget
+ * @y_layout: The y-offset at which the widget displays the
+ * #PangoLayout, relative to @widget
+ * @x: The x-coordinate relative to @coords at which to
+ * calculate the index
+ * @y: The y-coordinate relative to @coords at which to
+ * calculate the index
+ * @coords: An #AtkCoordType enumeration
+ *
+ * Gets the byte offset at the specified @x and @y in a #PangoLayout.
+ *
+ * Returns: the byte offset at the specified @x and @y in a
+ * #PangoLayout
+ **/
+gint
+gail_misc_get_index_at_point_in_layout (GtkWidget *widget,
+ PangoLayout *layout,
+ gint x_layout,
+ gint y_layout,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ gint index, x_window, y_window, x_toplevel, y_toplevel;
+ gint x_temp, y_temp;
+ gboolean ret;
+
+ gail_misc_get_origins (widget, &x_window, &y_window,
+ &x_toplevel, &y_toplevel);
+ x_temp = x - x_layout - x_window;
+ y_temp = y - y_layout - y_window;
+ if (coords == ATK_XY_WINDOW)
+ {
+ x_temp += x_toplevel;
+ y_temp += y_toplevel;
+ }
+ else if (coords != ATK_XY_SCREEN)
+ return -1;
+
+ ret = pango_layout_xy_to_index (layout,
+ x_temp * PANGO_SCALE,
+ y_temp * PANGO_SCALE,
+ &index, NULL);
+ if (!ret)
+ {
+ if (x_temp < 0 || y_temp < 0)
+ index = 0;
+ else
+ index = -1;
+ }
+ return index;
+}
+
+/**
+ * gail_misc_add_attribute:
+ * @attrib_set: The #AtkAttributeSet to add the attribute to
+ * @attr: The AtkTextAttrribute which identifies the attribute to be added
+ * @value: The attribute value
+ *
+ * Creates an #AtkAttribute from @attr and @value, and adds it
+ * to @attrib_set.
+ *
+ * Returns: A pointer to the new #AtkAttributeSet.
+ **/
+AtkAttributeSet*
+gail_misc_add_attribute (AtkAttributeSet *attrib_set,
+ AtkTextAttribute attr,
+ gchar *value)
+{
+ AtkAttributeSet *return_set;
+ AtkAttribute *at = g_malloc (sizeof (AtkAttribute));
+ at->name = g_strdup (atk_text_attribute_get_name (attr));
+ at->value = value;
+ return_set = g_slist_prepend(attrib_set, at);
+ return return_set;
+}
+
+/**
+ * gail_misc_layout_get_run_attributes:
+ * @attrib_set: The #AtkAttributeSet to add the attribute to
+ * @layout: The PangoLayout from which the attributes will be obtained
+ * @text: The text
+ * @offset: The offset at which the attributes are required
+ * @start_offset: The start offset of the current run
+ * @end_offset: The end offset of the current run
+ *
+ * Adds the attributes for the run starting at offset to the specified
+ * attribute set.
+ *
+ * Returns: A pointer to the #AtkAttributeSet.
+ **/
+AtkAttributeSet*
+gail_misc_layout_get_run_attributes (AtkAttributeSet *attrib_set,
+ PangoLayout *layout,
+ const gchar *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ PangoAttrIterator *iter;
+ PangoAttrList *attr;
+ PangoAttrString *pango_string;
+ PangoAttrInt *pango_int;
+ PangoAttrColor *pango_color;
+ PangoAttrLanguage *pango_lang;
+ PangoAttrFloat *pango_float;
+ gint index, start_index, end_index;
+ gboolean is_next = TRUE;
+ gchar *value = NULL;
+ glong len;
+
+ len = g_utf8_strlen (text, -1);
+ /* Grab the attributes of the PangoLayout, if any */
+ if ((attr = pango_layout_get_attributes (layout)) == NULL)
+ {
+ *start_offset = 0;
+ *end_offset = len;
+ return attrib_set;
+ }
+ iter = pango_attr_list_get_iterator (attr);
+ /* Get invariant range offsets */
+ /* If offset out of range, set offset in range */
+ if (offset > len)
+ offset = len;
+ else if (offset < 0)
+ offset = 0;
+
+ index = g_utf8_offset_to_pointer (text, offset) - text;
+ pango_attr_iterator_range (iter, &start_index, &end_index);
+ while (is_next)
+ {
+ if (index >= start_index && index < end_index)
+ {
+ *start_offset = g_utf8_pointer_to_offset (text,
+ text + start_index);
+ if (end_index == G_MAXINT)
+ /* Last iterator */
+ end_index = len;
+
+ *end_offset = g_utf8_pointer_to_offset (text,
+ text + end_index);
+ break;
+ }
+ is_next = pango_attr_iterator_next (iter);
+ pango_attr_iterator_range (iter, &start_index, &end_index);
+ }
+ /* Get attributes */
+ if ((pango_string = (PangoAttrString*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_FAMILY)) != NULL)
+ {
+ value = g_strdup_printf("%s", pango_string->value);
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_FAMILY_NAME,
+ value);
+ }
+ if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_STYLE)) != NULL)
+ {
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_STYLE,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, pango_int->value)));
+ }
+ if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_WEIGHT)) != NULL)
+ {
+ value = g_strdup_printf("%i", pango_int->value);
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_WEIGHT,
+ value);
+ }
+ if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_VARIANT)) != NULL)
+ {
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_VARIANT,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, pango_int->value)));
+ }
+ if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_STRETCH)) != NULL)
+ {
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_STRETCH,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, pango_int->value)));
+ }
+ if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_SIZE)) != NULL)
+ {
+ value = g_strdup_printf("%i", pango_int->value / PANGO_SCALE);
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_SIZE,
+ value);
+ }
+ if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_UNDERLINE)) != NULL)
+ {
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_UNDERLINE,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, pango_int->value)));
+ }
+ if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_STRIKETHROUGH)) != NULL)
+ {
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_STRIKETHROUGH,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, pango_int->value)));
+ }
+ if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_RISE)) != NULL)
+ {
+ value = g_strdup_printf("%i", pango_int->value);
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_RISE,
+ value);
+ }
+ if ((pango_lang = (PangoAttrLanguage*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_LANGUAGE)) != NULL)
+ {
+ value = g_strdup( pango_language_to_string( pango_lang->value));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_LANGUAGE,
+ value);
+ }
+ if ((pango_float = (PangoAttrFloat*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_SCALE)) != NULL)
+ {
+ value = g_strdup_printf("%g", pango_float->value);
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_SCALE,
+ value);
+ }
+ if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_FOREGROUND)) != NULL)
+ {
+ value = g_strdup_printf ("%u,%u,%u",
+ pango_color->color.red,
+ pango_color->color.green,
+ pango_color->color.blue);
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_FG_COLOR,
+ value);
+ }
+ if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter,
+ PANGO_ATTR_BACKGROUND)) != NULL)
+ {
+ value = g_strdup_printf ("%u,%u,%u",
+ pango_color->color.red,
+ pango_color->color.green,
+ pango_color->color.blue);
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_BG_COLOR,
+ value);
+ }
+ pango_attr_iterator_destroy (iter);
+ return attrib_set;
+}
+
+/**
+ * gail_misc_get_default_attributes:
+ * @attrib_set: The #AtkAttributeSet to add the attribute to
+ * @layout: The PangoLayout from which the attributes will be obtained
+ * @widget: The GtkWidget for which the default attributes are required.
+ *
+ * Adds the default attributes to the specified attribute set.
+ *
+ * Returns: A pointer to the #AtkAttributeSet.
+ **/
+AtkAttributeSet*
+gail_misc_get_default_attributes (AtkAttributeSet *attrib_set,
+ PangoLayout *layout,
+ GtkWidget *widget)
+{
+ PangoContext *context;
+ GtkStyleContext *style_context;
+ gint int_value;
+ PangoWrapMode mode;
+ GdkRGBA color;
+ gchar *value;
+
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_DIRECTION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
+ gtk_widget_get_direction (widget))));
+
+ context = pango_layout_get_context (layout);
+ if (context)
+ {
+ PangoLanguage* language;
+ PangoFontDescription* font;
+
+ language = pango_context_get_language (context);
+ if (language)
+ {
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_LANGUAGE,
+ g_strdup (pango_language_to_string (language)));
+ }
+ font = pango_context_get_font_description (context);
+ if (font)
+ {
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_STYLE,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE,
+ pango_font_description_get_style (font))));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_VARIANT,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT,
+ pango_font_description_get_variant (font))));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_STRETCH,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH,
+ pango_font_description_get_stretch (font))));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_FAMILY_NAME,
+ g_strdup (pango_font_description_get_family (font)));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_WEIGHT,
+ g_strdup_printf ("%d",
+ pango_font_description_get_weight (font)));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_SIZE,
+ g_strdup_printf ("%i",
+ pango_font_description_get_size (font) / PANGO_SCALE));
+ }
+ }
+ if (pango_layout_get_justify (layout))
+ {
+ int_value = 3;
+ }
+ else
+ {
+ PangoAlignment align;
+
+ align = pango_layout_get_alignment (layout);
+ if (align == PANGO_ALIGN_LEFT)
+ int_value = 0;
+ else if (align == PANGO_ALIGN_CENTER)
+ int_value = 2;
+ else /* if (align == PANGO_ALIGN_RIGHT) */
+ int_value = 1;
+ }
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_JUSTIFICATION,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION,
+ int_value)));
+ mode = pango_layout_get_wrap (layout);
+ if (mode == PANGO_WRAP_WORD)
+ int_value = 2;
+ else /* if (mode == PANGO_WRAP_CHAR) */
+ int_value = 1;
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_WRAP_MODE,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE,
+ int_value)));
+
+ style_context = gtk_widget_get_style_context (widget);
+
+ gtk_style_context_get_background_color (style_context, 0, &color);
+ value = g_strdup_printf ("%u,%u,%u",
+ (guint) ceil (color.red * 65536 - color.red),
+ (guint) ceil (color.green * 65536 - color.green),
+ (guint) ceil (color.blue * 65536 - color.blue));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_BG_COLOR,
+ value);
+
+ gtk_style_context_get_color (style_context, 0, &color);
+ value = g_strdup_printf ("%u,%u,%u",
+ (guint) ceil (color.red * 65536 - color.red),
+ (guint) ceil (color.green * 65536 - color.green),
+ (guint) ceil (color.blue * 65536 - color.blue));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_FG_COLOR,
+ value);
+
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_FG_STIPPLE,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_FG_STIPPLE,
+ 0)));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_BG_STIPPLE,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_STIPPLE,
+ 0)));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_STRIKETHROUGH,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH,
+ 0)));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_UNDERLINE,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE,
+ 0)));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_RISE,
+ g_strdup_printf ("%i", 0));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_SCALE,
+ g_strdup_printf ("%g", 1.0));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_BG_FULL_HEIGHT,
+ g_strdup_printf ("%i", 0));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP,
+ g_strdup_printf ("%i", 0));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_PIXELS_BELOW_LINES,
+ g_strdup_printf ("%i", 0));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_PIXELS_ABOVE_LINES,
+ g_strdup_printf ("%i", 0));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_EDITABLE,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE,
+ 0)));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_INVISIBLE,
+ g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_INVISIBLE,
+ 0)));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_INDENT,
+ g_strdup_printf ("%i", 0));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_RIGHT_MARGIN,
+ g_strdup_printf ("%i", 0));
+ attrib_set = gail_misc_add_attribute (attrib_set,
+ ATK_TEXT_ATTR_LEFT_MARGIN,
+ g_strdup_printf ("%i", 0));
+ return attrib_set;
+}
+
+/**
+ * gail_misc_get_origins:
+ * @widget: a #GtkWidget
+ * @x_window: the x-origin of the widget->window
+ * @y_window: the y-origin of the widget->window
+ * @x_toplevel: the x-origin of the toplevel window for widget->window
+ * @y_toplevel: the y-origin of the toplevel window for widget->window
+ *
+ * Gets the origin of the widget window, and the origin of the
+ * widgets top-level window.
+ **/
+void
+gail_misc_get_origins (GtkWidget *widget,
+ gint *x_window,
+ gint *y_window,
+ gint *x_toplevel,
+ gint *y_toplevel)
+{
+ GdkWindow *window;
+
+ if (GTK_IS_TREE_VIEW (widget))
+ window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget));
+ else
+ window = gtk_widget_get_window (widget);
+
+ gdk_window_get_origin (window, x_window, y_window);
+ window = gdk_window_get_toplevel (gtk_widget_get_window (widget));
+ gdk_window_get_origin (window, x_toplevel, y_toplevel);
+}
+
+/**
+ * gail_misc_buffer_get_run_attributes:
+ * @buffer: The #GtkTextBuffer for which the attributes will be obtained
+ * @offset: The offset at which the attributes are required
+ * @start_offset: The start offset of the current run
+ * @end_offset: The end offset of the current run
+ *
+ * Creates an AtkAttributeSet which contains the attributes for the
+ * run starting at offset.
+ *
+ * Returns: A pointer to the #AtkAttributeSet.
+ **/
+AtkAttributeSet*
+gail_misc_buffer_get_run_attributes (GtkTextBuffer *buffer,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkTextIter iter;
+ AtkAttributeSet *attrib_set = NULL;
+ AtkAttribute *at;
+ GSList *tags, *temp_tags;
+ gdouble scale = 1;
+ gboolean val_set = FALSE;
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
+
+ gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
+ *end_offset = gtk_text_iter_get_offset (&iter);
+
+ gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
+ *start_offset = gtk_text_iter_get_offset (&iter);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
+
+ tags = gtk_text_iter_get_tags (&iter);
+ tags = g_slist_reverse (tags);
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "style-set", &val_set, NULL);
+ if (val_set)
+ {
+ PangoStyle style;
+ gchar *value;
+
+ g_object_get (tag, "style", &style, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, style));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STYLE, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "variant-set", &val_set, NULL);
+ if (val_set)
+ {
+ PangoVariant variant;
+ gchar *value;
+
+ g_object_get (tag, "variant", &variant, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, variant));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "stretch-set", &val_set, NULL);
+ if (val_set)
+ {
+ PangoStretch stretch;
+ gchar *value;
+
+ g_object_get (tag, "stretch", &stretch, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, stretch));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "justification-set", &val_set, NULL);
+ if (val_set)
+ {
+ GtkJustification justification;
+ gchar *value;
+
+ g_object_get (tag, "justification", &justification, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justification));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+ GtkTextDirection direction;
+
+ g_object_get (tag, "direction", &direction, NULL);
+
+ if (direction != GTK_TEXT_DIR_NONE)
+ {
+ gchar *value;
+ val_set = TRUE;
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, direction));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "wrap-mode-set", &val_set, NULL);
+ if (val_set)
+ {
+ GtkWrapMode wrap_mode;
+ gchar *value;
+
+ g_object_get (tag, "wrap-mode", &wrap_mode, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, wrap_mode));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "foreground-set", &val_set, NULL);
+ if (val_set)
+ {
+ GdkRGBA *rgba;
+ gchar *value;
+
+ g_object_get (tag, "foreground-rgba", &rgba, NULL);
+ value = g_strdup_printf ("%u,%u,%u",
+ (guint) rgba->red * 65535,
+ (guint) rgba->green * 65535,
+ (guint) rgba->blue * 65535);
+ gdk_rgba_free (rgba);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "background-set", &val_set, NULL);
+ if (val_set)
+ {
+ GdkRGBA *rgba;
+ gchar *value;
+
+ g_object_get (tag, "background-rgba", &rgba, NULL);
+ value = g_strdup_printf ("%u,%u,%u",
+ (guint) rgba->red * 65535,
+ (guint) rgba->green * 65535,
+ (guint) rgba->blue * 65535);
+ gdk_rgba_free (rgba);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "family-set", &val_set, NULL);
+
+ if (val_set)
+ {
+ gchar *value;
+ g_object_get (tag, "family", &value, NULL);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "language-set", &val_set, NULL);
+
+ if (val_set)
+ {
+ gchar *value;
+ g_object_get (tag, "language", &value, NULL);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "weight-set", &val_set, NULL);
+
+ if (val_set)
+ {
+ gint weight;
+ gchar *value;
+
+ g_object_get (tag, "weight", &weight, NULL);
+ value = g_strdup_printf ("%d", weight);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+
+ /*
+ * scale is special as the scale is the product of all scale values
+ * specified.
+ */
+ temp_tags = tags;
+ while (temp_tags)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+ gboolean scale_set;
+
+ g_object_get (tag, "scale-set", &scale_set, NULL);
+ if (scale_set)
+ {
+ gdouble font_scale;
+
+ g_object_get (tag, "scale", &font_scale, NULL);
+ val_set = TRUE;
+ scale *= font_scale;
+ }
+ temp_tags = temp_tags->next;
+ }
+ if (val_set)
+ {
+ at = g_malloc(sizeof(AtkAttribute));
+ at->name = g_strdup(atk_text_attribute_get_name (ATK_TEXT_ATTR_SCALE));
+ at->value = g_strdup_printf("%g", scale);
+ attrib_set = g_slist_prepend(attrib_set, at);
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "size-set", &val_set, NULL);
+ if (val_set)
+ {
+ gint size;
+ gchar *value;
+ g_object_get (tag, "size", &size, NULL);
+ value = g_strdup_printf ("%i", size);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "strikethrough-set", &val_set, NULL);
+ if (val_set)
+ {
+ gboolean strikethrough;
+ gchar *value;
+ g_object_get (tag, "strikethrough", &strikethrough, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, strikethrough));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "underline-set", &val_set, NULL);
+ if (val_set)
+ {
+ PangoUnderline underline;
+ gchar *value;
+ g_object_get (tag, "underline", &underline, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, underline));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "rise-set", &val_set, NULL);
+ if (val_set)
+ {
+ gint rise;
+ gchar *value;
+ g_object_get (tag, "rise", &rise, NULL);
+ value = g_strdup_printf ("%i", rise);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "background-full-height-set", &val_set, NULL);
+ if (val_set)
+ {
+ gboolean bg_full_height;
+ gchar *value;
+ g_object_get (tag, "background-full-height", &bg_full_height, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, bg_full_height));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "pixels-inside-wrap-set", &val_set, NULL);
+ if (val_set)
+ {
+ gint pixels;
+ gchar *value;
+ g_object_get (tag, "pixels-inside-wrap", &pixels, NULL);
+ value = g_strdup_printf ("%i", pixels);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "pixels-below-lines-set", &val_set, NULL);
+ if (val_set)
+ {
+ gint pixels;
+ gchar *value;
+ g_object_get (tag, "pixels-below-lines", &pixels, NULL);
+ value = g_strdup_printf ("%i", pixels);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "pixels-above-lines-set", &val_set, NULL);
+ if (val_set)
+ {
+ gint pixels;
+ gchar *value;
+ g_object_get (tag, "pixels-above-lines", &pixels, NULL);
+ value = g_strdup_printf ("%i", pixels);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "editable-set", &val_set, NULL);
+ if (val_set)
+ {
+ gboolean editable;
+ gchar *value;
+ g_object_get (tag, "editable", &editable, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, editable));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "invisible-set", &val_set, NULL);
+ if (val_set)
+ {
+ gboolean invisible;
+ gchar *value;
+ g_object_get (tag, "invisible", &invisible, NULL);
+ value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_INVISIBLE, invisible));
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "indent-set", &val_set, NULL);
+ if (val_set)
+ {
+ gint indent;
+ gchar *value;
+ g_object_get (tag, "indent", &indent, NULL);
+ value = g_strdup_printf ("%i", indent);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "right-margin-set", &val_set, NULL);
+ if (val_set)
+ {
+ gint margin;
+ gchar *value;
+ g_object_get (tag, "right-margin", &margin, NULL);
+ value = g_strdup_printf ("%i", margin);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ temp_tags = tags;
+ while (temp_tags && !val_set)
+ {
+ GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
+
+ g_object_get (tag, "left-margin-set", &val_set, NULL);
+ if (val_set)
+ {
+ gint margin;
+ gchar *value;
+ g_object_get (tag, "left-margin", &margin, NULL);
+ value = g_strdup_printf ("%i", margin);
+ attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
+ }
+ temp_tags = temp_tags->next;
+ }
+ val_set = FALSE;
+
+ g_slist_free (tags);
+ return attrib_set;
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_MISC_H__
+#define __GAIL_MISC_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <pango/pango.h>
+
+G_BEGIN_DECLS
+
+AtkAttributeSet* gail_misc_add_attribute (AtkAttributeSet *attrib_set,
+ AtkTextAttribute attr,
+ gchar *value);
+AtkAttributeSet* gail_misc_layout_get_run_attributes
+ (AtkAttributeSet *attrib_set,
+ PangoLayout *layout,
+ const gchar *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+
+AtkAttributeSet* gail_misc_get_default_attributes (AtkAttributeSet *attrib_set,
+ PangoLayout *layout,
+ GtkWidget *widget);
+
+void gail_misc_get_extents_from_pango_rectangle
+ (GtkWidget *widget,
+ PangoRectangle *char_rect,
+ gint x_layout,
+ gint y_layout,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords);
+
+gint gail_misc_get_index_at_point_in_layout
+ (GtkWidget *widget,
+ PangoLayout *layout,
+ gint x_layout,
+ gint y_layout,
+ gint x,
+ gint y,
+ AtkCoordType coords);
+
+void gail_misc_get_origins (GtkWidget *widget,
+ gint *x_window,
+ gint *y_window,
+ gint *x_toplevel,
+ gint *y_toplevel);
+
+AtkAttributeSet* gail_misc_buffer_get_run_attributes
+ (GtkTextBuffer *buffer,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+
+G_END_DECLS
+
+#endif /*__GAIL_MISC_H__ */
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include "gailtextutil.h"
+
+/**
+ * SECTION:gailtextutil
+ * @Short_description: GailTextUtil is a utility class which can be used to
+ * implement some of the #AtkText functions for accessible objects
+ * which implement #AtkText.
+ * @Title: GailTextUtil
+ *
+ * GailTextUtil is a utility class which can be used to implement the
+ * #AtkText functions which get text for accessible objects which implement
+ * #AtkText.
+ *
+ * In GAIL it is used by the accsesible objects for #GnomeCanvasText, #GtkEntry,
+ * #GtkLabel, #GtkCellRendererText and #GtkTextView.
+ */
+
+static void gail_text_util_class_init (GailTextUtilClass *klass);
+
+static void gail_text_util_init (GailTextUtil *textutil);
+static void gail_text_util_finalize (GObject *object);
+
+
+static void get_pango_text_offsets (PangoLayout *layout,
+ GtkTextBuffer *buffer,
+ GailOffsetType function,
+ AtkTextBoundary boundary_type,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset,
+ GtkTextIter *start_iter,
+ GtkTextIter *end_iter);
+static GObjectClass *parent_class = NULL;
+
+GType
+gail_text_util_get_type(void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ const GTypeInfo tinfo =
+ {
+ sizeof (GailTextUtilClass),
+ (GBaseInitFunc) NULL, /* base init */
+ (GBaseFinalizeFunc) NULL, /* base finalize */
+ (GClassInitFunc) gail_text_util_class_init,
+ (GClassFinalizeFunc) NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof(GailTextUtil),
+ 0, /* nb preallocs */
+ (GInstanceInitFunc) gail_text_util_init,
+ NULL, /* value table */
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT, "GailTextUtil", &tinfo, 0);
+ }
+ return type;
+}
+
+/**
+ * gail_text_util_new:
+ *
+ * This function creates a new GailTextUtil object.
+ *
+ * Returns: the GailTextUtil object
+ **/
+GailTextUtil*
+gail_text_util_new (void)
+{
+ return GAIL_TEXT_UTIL (g_object_new (GAIL_TYPE_TEXT_UTIL, NULL));
+}
+
+static void
+gail_text_util_init (GailTextUtil *textutil)
+{
+ textutil->buffer = NULL;
+}
+
+static void
+gail_text_util_class_init (GailTextUtilClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->finalize = gail_text_util_finalize;
+}
+
+static void
+gail_text_util_finalize (GObject *object)
+{
+ GailTextUtil *textutil = GAIL_TEXT_UTIL (object);
+
+ if (textutil->buffer)
+ g_object_unref (textutil->buffer);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+/**
+ * gail_text_util_text_setup:
+ * @textutil: The #GailTextUtil to be initialized.
+ * @text: A gchar* which points to the text to be stored in the GailTextUtil
+ *
+ * This function initializes the GailTextUtil with the specified character string,
+ **/
+void
+gail_text_util_text_setup (GailTextUtil *textutil,
+ const gchar *text)
+{
+ g_return_if_fail (GAIL_IS_TEXT_UTIL (textutil));
+
+ if (textutil->buffer)
+ {
+ if (!text)
+ {
+ g_object_unref (textutil->buffer);
+ textutil->buffer = NULL;
+ return;
+ }
+ }
+ else
+ {
+ textutil->buffer = gtk_text_buffer_new (NULL);
+ }
+
+ gtk_text_buffer_set_text (textutil->buffer, text, -1);
+}
+
+/**
+ * gail_text_util_buffer_setup:
+ * @textutil: A #GailTextUtil to be initialized
+ * @buffer: The #GtkTextBuffer which identifies the text to be stored in the GailUtil.
+ *
+ * This function initializes the GailTextUtil with the specified GtkTextBuffer
+ **/
+void
+gail_text_util_buffer_setup (GailTextUtil *textutil,
+ GtkTextBuffer *buffer)
+{
+ g_return_if_fail (GAIL_IS_TEXT_UTIL (textutil));
+
+ textutil->buffer = g_object_ref (buffer);
+}
+
+/**
+ * gail_text_util_get_text:
+ * @textutil: A #GailTextUtil
+ * @layout: A gpointer which is a PangoLayout, a GtkTreeView of NULL
+ * @function: An enumeration specifying whether to return the text before, at, or
+ * after the offset.
+ * @boundary_type: The boundary type.
+ * @offset: The offset of the text in the GailTextUtil
+ * @start_offset: Address of location in which the start offset is returned
+ * @end_offset: Address of location in which the end offset is returned
+ *
+ * This function gets the requested substring from the text in the GtkTextUtil.
+ * The layout is used only for getting the text on a line. The value is NULL
+ * for a GtkTextView which is not wrapped, is a GtkTextView for a GtkTextView
+ * which is wrapped and is a PangoLayout otherwise.
+ *
+ * Returns: the substring requested
+ **/
+gchar*
+gail_text_util_get_text (GailTextUtil *textutil,
+ gpointer layout,
+ GailOffsetType function,
+ AtkTextBoundary boundary_type,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GtkTextIter start, end;
+ gint line_number;
+ GtkTextBuffer *buffer;
+
+ g_return_val_if_fail (GAIL_IS_TEXT_UTIL (textutil), NULL);
+
+ buffer = textutil->buffer;
+ if (buffer == NULL)
+ {
+ *start_offset = 0;
+ *end_offset = 0;
+ return NULL;
+ }
+
+ if (!gtk_text_buffer_get_char_count (buffer))
+ {
+ *start_offset = 0;
+ *end_offset = 0;
+ return g_strdup ("");
+ }
+ gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
+
+
+ end = start;
+
+ switch (function)
+ {
+ case GAIL_BEFORE_OFFSET:
+ switch (boundary_type)
+ {
+ case ATK_TEXT_BOUNDARY_CHAR:
+ gtk_text_iter_backward_char(&start);
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_START:
+ if (!gtk_text_iter_starts_word (&start))
+ gtk_text_iter_backward_word_start (&start);
+ end = start;
+ gtk_text_iter_backward_word_start(&start);
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_END:
+ if (gtk_text_iter_inside_word (&start) &&
+ !gtk_text_iter_starts_word (&start))
+ gtk_text_iter_backward_word_start (&start);
+ while (!gtk_text_iter_ends_word (&start))
+ {
+ if (!gtk_text_iter_backward_char (&start))
+ break;
+ }
+ end = start;
+ gtk_text_iter_backward_word_start(&start);
+ while (!gtk_text_iter_ends_word (&start))
+ {
+ if (!gtk_text_iter_backward_char (&start))
+ break;
+ }
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_START:
+ if (!gtk_text_iter_starts_sentence (&start))
+ gtk_text_iter_backward_sentence_start (&start);
+ end = start;
+ gtk_text_iter_backward_sentence_start (&start);
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_END:
+ if (gtk_text_iter_inside_sentence (&start) &&
+ !gtk_text_iter_starts_sentence (&start))
+ gtk_text_iter_backward_sentence_start (&start);
+ while (!gtk_text_iter_ends_sentence (&start))
+ {
+ if (!gtk_text_iter_backward_char (&start))
+ break;
+ }
+ end = start;
+ gtk_text_iter_backward_sentence_start (&start);
+ while (!gtk_text_iter_ends_sentence (&start))
+ {
+ if (!gtk_text_iter_backward_char (&start))
+ break;
+ }
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ if (layout == NULL)
+ {
+ line_number = gtk_text_iter_get_line (&start);
+ if (line_number == 0)
+ {
+ gtk_text_buffer_get_iter_at_offset (buffer,
+ &start, 0);
+ }
+ else
+ {
+ gtk_text_iter_backward_line (&start);
+ gtk_text_iter_forward_line (&start);
+ }
+ end = start;
+ gtk_text_iter_backward_line (&start);
+ }
+ else if GTK_IS_TEXT_VIEW (layout)
+ {
+ GtkTextView *view = GTK_TEXT_VIEW (layout);
+
+ gtk_text_view_backward_display_line_start (view, &start);
+ end = start;
+ gtk_text_view_backward_display_line (view, &start);
+ }
+ else if (PANGO_IS_LAYOUT (layout))
+ get_pango_text_offsets (PANGO_LAYOUT (layout),
+ buffer,
+ function,
+ boundary_type,
+ offset,
+ start_offset,
+ end_offset,
+ &start,
+ &end);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_END:
+ if (layout == NULL)
+ {
+ line_number = gtk_text_iter_get_line (&start);
+ if (line_number == 0)
+ {
+ gtk_text_buffer_get_iter_at_offset (buffer,
+ &start, 0);
+ end = start;
+ }
+ else
+ {
+ gtk_text_iter_backward_line (&start);
+ end = start;
+ while (!gtk_text_iter_ends_line (&start))
+ {
+ if (!gtk_text_iter_backward_char (&start))
+ break;
+ }
+ gtk_text_iter_forward_to_line_end (&end);
+ }
+ }
+ else if GTK_IS_TEXT_VIEW (layout)
+ {
+ GtkTextView *view = GTK_TEXT_VIEW (layout);
+
+ gtk_text_view_backward_display_line_start (view, &start);
+ if (!gtk_text_iter_is_start (&start))
+ {
+ gtk_text_view_backward_display_line (view, &start);
+ end = start;
+ if (!gtk_text_iter_is_start (&start))
+ {
+ gtk_text_view_backward_display_line (view, &start);
+ gtk_text_view_forward_display_line_end (view, &start);
+ }
+ gtk_text_view_forward_display_line_end (view, &end);
+ }
+ else
+ {
+ end = start;
+ }
+ }
+ else if (PANGO_IS_LAYOUT (layout))
+ get_pango_text_offsets (PANGO_LAYOUT (layout),
+ buffer,
+ function,
+ boundary_type,
+ offset,
+ start_offset,
+ end_offset,
+ &start,
+ &end);
+ break;
+ }
+ break;
+
+ case GAIL_AT_OFFSET:
+ switch (boundary_type)
+ {
+ case ATK_TEXT_BOUNDARY_CHAR:
+ gtk_text_iter_forward_char (&end);
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_START:
+ if (!gtk_text_iter_starts_word (&start))
+ gtk_text_iter_backward_word_start (&start);
+ if (gtk_text_iter_inside_word (&end))
+ gtk_text_iter_forward_word_end (&end);
+ while (!gtk_text_iter_starts_word (&end))
+ {
+ if (!gtk_text_iter_forward_char (&end))
+ break;
+ }
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_END:
+ if (gtk_text_iter_inside_word (&start) &&
+ !gtk_text_iter_starts_word (&start))
+ gtk_text_iter_backward_word_start (&start);
+ while (!gtk_text_iter_ends_word (&start))
+ {
+ if (!gtk_text_iter_backward_char (&start))
+ break;
+ }
+ gtk_text_iter_forward_word_end (&end);
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_START:
+ if (!gtk_text_iter_starts_sentence (&start))
+ gtk_text_iter_backward_sentence_start (&start);
+ if (gtk_text_iter_inside_sentence (&end))
+ gtk_text_iter_forward_sentence_end (&end);
+ while (!gtk_text_iter_starts_sentence (&end))
+ {
+ if (!gtk_text_iter_forward_char (&end))
+ break;
+ }
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_END:
+ if (gtk_text_iter_inside_sentence (&start) &&
+ !gtk_text_iter_starts_sentence (&start))
+ gtk_text_iter_backward_sentence_start (&start);
+ while (!gtk_text_iter_ends_sentence (&start))
+ {
+ if (!gtk_text_iter_backward_char (&start))
+ break;
+ }
+ gtk_text_iter_forward_sentence_end (&end);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ if (layout == NULL)
+ {
+ line_number = gtk_text_iter_get_line (&start);
+ if (line_number == 0)
+ {
+ gtk_text_buffer_get_iter_at_offset (buffer,
+ &start, 0);
+ }
+ else
+ {
+ gtk_text_iter_backward_line (&start);
+ gtk_text_iter_forward_line (&start);
+ }
+ gtk_text_iter_forward_line (&end);
+ }
+ else if GTK_IS_TEXT_VIEW (layout)
+ {
+ GtkTextView *view = GTK_TEXT_VIEW (layout);
+
+ gtk_text_view_backward_display_line_start (view, &start);
+ /*
+ * The call to gtk_text_iter_forward_to_end() is needed
+ * because of bug 81960
+ */
+ if (!gtk_text_view_forward_display_line (view, &end))
+ gtk_text_iter_forward_to_end (&end);
+ }
+ else if PANGO_IS_LAYOUT (layout)
+ get_pango_text_offsets (PANGO_LAYOUT (layout),
+ buffer,
+ function,
+ boundary_type,
+ offset,
+ start_offset,
+ end_offset,
+ &start,
+ &end);
+
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_END:
+ if (layout == NULL)
+ {
+ line_number = gtk_text_iter_get_line (&start);
+ if (line_number == 0)
+ {
+ gtk_text_buffer_get_iter_at_offset (buffer,
+ &start, 0);
+ }
+ else
+ {
+ gtk_text_iter_backward_line (&start);
+ gtk_text_iter_forward_line (&start);
+ }
+ while (!gtk_text_iter_ends_line (&start))
+ {
+ if (!gtk_text_iter_backward_char (&start))
+ break;
+ }
+ gtk_text_iter_forward_to_line_end (&end);
+ }
+ else if GTK_IS_TEXT_VIEW (layout)
+ {
+ GtkTextView *view = GTK_TEXT_VIEW (layout);
+
+ gtk_text_view_backward_display_line_start (view, &start);
+ if (!gtk_text_iter_is_start (&start))
+ {
+ gtk_text_view_backward_display_line (view, &start);
+ gtk_text_view_forward_display_line_end (view, &start);
+ }
+ gtk_text_view_forward_display_line_end (view, &end);
+ }
+ else if PANGO_IS_LAYOUT (layout)
+ get_pango_text_offsets (PANGO_LAYOUT (layout),
+ buffer,
+ function,
+ boundary_type,
+ offset,
+ start_offset,
+ end_offset,
+ &start,
+ &end);
+ break;
+ }
+ break;
+
+ case GAIL_AFTER_OFFSET:
+ switch (boundary_type)
+ {
+ case ATK_TEXT_BOUNDARY_CHAR:
+ gtk_text_iter_forward_char(&start);
+ gtk_text_iter_forward_chars(&end, 2);
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_START:
+ if (gtk_text_iter_inside_word (&end))
+ gtk_text_iter_forward_word_end (&end);
+ while (!gtk_text_iter_starts_word (&end))
+ {
+ if (!gtk_text_iter_forward_char (&end))
+ break;
+ }
+ start = end;
+ if (!gtk_text_iter_is_end (&end))
+ {
+ gtk_text_iter_forward_word_end (&end);
+ while (!gtk_text_iter_starts_word (&end))
+ {
+ if (!gtk_text_iter_forward_char (&end))
+ break;
+ }
+ }
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_END:
+ gtk_text_iter_forward_word_end (&end);
+ start = end;
+ if (!gtk_text_iter_is_end (&end))
+ gtk_text_iter_forward_word_end (&end);
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_START:
+ if (gtk_text_iter_inside_sentence (&end))
+ gtk_text_iter_forward_sentence_end (&end);
+ while (!gtk_text_iter_starts_sentence (&end))
+ {
+ if (!gtk_text_iter_forward_char (&end))
+ break;
+ }
+ start = end;
+ if (!gtk_text_iter_is_end (&end))
+ {
+ gtk_text_iter_forward_sentence_end (&end);
+ while (!gtk_text_iter_starts_sentence (&end))
+ {
+ if (!gtk_text_iter_forward_char (&end))
+ break;
+ }
+ }
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_END:
+ gtk_text_iter_forward_sentence_end (&end);
+ start = end;
+ if (!gtk_text_iter_is_end (&end))
+ gtk_text_iter_forward_sentence_end (&end);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ if (layout == NULL)
+ {
+ gtk_text_iter_forward_line (&end);
+ start = end;
+ gtk_text_iter_forward_line (&end);
+ }
+ else if GTK_IS_TEXT_VIEW (layout)
+ {
+ GtkTextView *view = GTK_TEXT_VIEW (layout);
+
+ gtk_text_view_forward_display_line (view, &end);
+ start = end;
+ gtk_text_view_forward_display_line (view, &end);
+ }
+ else if (PANGO_IS_LAYOUT (layout))
+ get_pango_text_offsets (PANGO_LAYOUT (layout),
+ buffer,
+ function,
+ boundary_type,
+ offset,
+ start_offset,
+ end_offset,
+ &start,
+ &end);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_END:
+ if (layout == NULL)
+ {
+ gtk_text_iter_forward_line (&start);
+ end = start;
+ if (!gtk_text_iter_is_end (&start))
+ {
+ while (!gtk_text_iter_ends_line (&start))
+ {
+ if (!gtk_text_iter_backward_char (&start))
+ break;
+ }
+ gtk_text_iter_forward_to_line_end (&end);
+ }
+ }
+ else if GTK_IS_TEXT_VIEW (layout)
+ {
+ GtkTextView *view = GTK_TEXT_VIEW (layout);
+
+ gtk_text_view_forward_display_line_end (view, &end);
+ start = end;
+ gtk_text_view_forward_display_line (view, &end);
+ gtk_text_view_forward_display_line_end (view, &end);
+ }
+ else if (PANGO_IS_LAYOUT (layout))
+ get_pango_text_offsets (PANGO_LAYOUT (layout),
+ buffer,
+ function,
+ boundary_type,
+ offset,
+ start_offset,
+ end_offset,
+ &start,
+ &end);
+ break;
+ }
+ break;
+ }
+ *start_offset = gtk_text_iter_get_offset (&start);
+ *end_offset = gtk_text_iter_get_offset (&end);
+
+ return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+}
+
+/**
+ * gail_text_util_get_substring:
+ * @textutil: A #GailTextUtil
+ * @start_pos: The start position of the substring
+ * @end_pos: The end position of the substring.
+ *
+ * Gets the substring indicated by @start_pos and @end_pos
+ *
+ * Returns: the substring indicated by @start_pos and @end_pos
+ **/
+gchar*
+gail_text_util_get_substring (GailTextUtil *textutil,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkTextIter start, end;
+ GtkTextBuffer *buffer;
+
+ g_return_val_if_fail(GAIL_IS_TEXT_UTIL (textutil), NULL);
+
+ buffer = textutil->buffer;
+ if (buffer == NULL)
+ return NULL;
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
+ if (end_pos < 0)
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ else
+ gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
+
+ return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+}
+
+static void
+get_pango_text_offsets (PangoLayout *layout,
+ GtkTextBuffer *buffer,
+ GailOffsetType function,
+ AtkTextBoundary boundary_type,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset,
+ GtkTextIter *start_iter,
+ GtkTextIter *end_iter)
+{
+ PangoLayoutIter *iter;
+ PangoLayoutLine *line, *prev_line = NULL, *prev_prev_line = NULL;
+ gint index, start_index, end_index;
+ const gchar *text;
+ gboolean found = FALSE;
+
+ text = pango_layout_get_text (layout);
+ index = g_utf8_offset_to_pointer (text, offset) - text;
+ iter = pango_layout_get_iter (layout);
+ do
+ {
+ line = pango_layout_iter_get_line (iter);
+ start_index = line->start_index;
+ end_index = start_index + line->length;
+
+ if (index >= start_index && index <= end_index)
+ {
+ /*
+ * Found line for offset
+ */
+ switch (function)
+ {
+ case GAIL_BEFORE_OFFSET:
+ /*
+ * We want the previous line
+ */
+ if (prev_line)
+ {
+ switch (boundary_type)
+ {
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ end_index = start_index;
+ start_index = prev_line->start_index;
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_END:
+ if (prev_prev_line)
+ start_index = prev_prev_line->start_index +
+ prev_prev_line->length;
+ end_index = prev_line->start_index + prev_line->length;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ }
+ else
+ start_index = end_index = 0;
+ break;
+ case GAIL_AT_OFFSET:
+ switch (boundary_type)
+ {
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ if (pango_layout_iter_next_line (iter))
+ end_index = pango_layout_iter_get_line (iter)->start_index;
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_END:
+ if (prev_line)
+ start_index = prev_line->start_index +
+ prev_line->length;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ break;
+ case GAIL_AFTER_OFFSET:
+ /*
+ * We want the next line
+ */
+ if (pango_layout_iter_next_line (iter))
+ {
+ line = pango_layout_iter_get_line (iter);
+ switch (boundary_type)
+ {
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ start_index = line->start_index;
+ if (pango_layout_iter_next_line (iter))
+ end_index = pango_layout_iter_get_line (iter)->start_index;
+ else
+ end_index = start_index + line->length;
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_END:
+ start_index = end_index;
+ end_index = line->start_index + line->length;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ }
+ else
+ start_index = end_index;
+ break;
+ }
+ found = TRUE;
+ break;
+ }
+ prev_prev_line = prev_line;
+ prev_line = line;
+ }
+ while (pango_layout_iter_next_line (iter));
+
+ if (!found)
+ {
+ start_index = prev_line->start_index + prev_line->length;
+ end_index = start_index;
+ }
+ pango_layout_iter_free (iter);
+ *start_offset = g_utf8_pointer_to_offset (text, text + start_index);
+ *end_offset = g_utf8_pointer_to_offset (text, text + end_index);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, start_iter, *start_offset);
+ gtk_text_buffer_get_iter_at_offset (buffer, end_iter, *end_offset);
+}
--- /dev/null
+/* GAIL - The GNOME Accessibility Implementation Library
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GAIL_TEXT_UTIL_H__
+#define __GAIL_TEXT_UTIL_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GAIL_TYPE_TEXT_UTIL (gail_text_util_get_type ())
+#define GAIL_TEXT_UTIL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TEXT_UTIL, GailTextUtil))
+#define GAIL_TEXT_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TEXT_UTIL, GailTextUtilClass))
+#define GAIL_IS_TEXT_UTIL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TEXT_UTIL))
+#define GAIL_IS_TEXT_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TEXT_UTIL))
+#define GAIL_TEXT_UTIL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TEXT_UTIL, GailTextUtilClass))
+
+/**
+ *GailOffsetType:
+ *@GAIL_BEFORE_OFFSET: Text before offset is required.
+ *@GAIL_AT_OFFSET: Text at offset is required,
+ *@GAIL_AFTER_OFFSET: Text after offset is required.
+ *
+ * Specifies which of the functions atk_text_get_text_before_offset(),
+ * atk_text_get_text_at_offset(), atk_text_get_text_after_offset() the
+ * function gail_text_util_get_text() is being called for.
+ **/
+typedef enum
+{
+ GAIL_BEFORE_OFFSET,
+ GAIL_AT_OFFSET,
+ GAIL_AFTER_OFFSET
+}GailOffsetType;
+
+typedef struct _GailTextUtil GailTextUtil;
+typedef struct _GailTextUtilClass GailTextUtilClass;
+
+struct _GailTextUtil
+{
+ GObject parent;
+
+ GtkTextBuffer *buffer;
+};
+
+struct _GailTextUtilClass
+{
+ GObjectClass parent_class;
+};
+
+GType gail_text_util_get_type (void);
+GailTextUtil* gail_text_util_new (void);
+
+void gail_text_util_text_setup (GailTextUtil *textutil,
+ const gchar *text);
+void gail_text_util_buffer_setup (GailTextUtil *textutil,
+ GtkTextBuffer *buffer);
+gchar* gail_text_util_get_text (GailTextUtil *textutil,
+ gpointer layout,
+ GailOffsetType function,
+ AtkTextBoundary boundary_type,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset);
+gchar* gail_text_util_get_substring (GailTextUtil *textutil,
+ gint start_pos,
+ gint end_pos);
+
+G_END_DECLS
+
+#endif /*__GAIL_TEXT_UTIL_H__ */
--- /dev/null
+EXPORTS
+ gail_misc_add_attribute
+ gail_misc_buffer_get_run_attributes
+ gail_misc_get_default_attributes
+ gail_misc_get_extents_from_pango_rectangle
+ gail_misc_get_index_at_point_in_layout
+ gail_misc_get_origins
+ gail_misc_layout_get_run_attributes
+ gail_text_util_buffer_setup
+ gail_text_util_get_substring
+ gail_text_util_get_text
+ gail_text_util_get_type
+ gail_text_util_new
+ gail_text_util_text_setup
--- /dev/null
+## Makefile.am for gtk+/tests
+include $(top_srcdir)/Makefile.decl
+
+if PLATFORM_WIN32
+no_undefined = -no-undefined
+endif
+
+moduledir = $(libdir)/gtk-3.0/modules
+
+if !OS_WIN32
+module_LTLIBRARIES = \
+ libferret.la
+endif
+
+noinst_LTLIBRARIES = \
+ libtestaction.la \
+ libtestbutton.la \
+ libtestcombo.la \
+ libtestcomponent.la \
+ libtestimage.la \
+ libtestnotebook.la \
+ libtestobject.la \
+ libtestmenuitem.la \
+ libtestpaned.la \
+ libtestprops.la \
+ libtestselection.la \
+ libteststatusbar.la \
+ libtesttable.la \
+ libtesttext.la \
+ libtesttoplevel.la \
+ libtesttreetable.la \
+ libtestvalues.la
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/gdk \
+ -I$(top_builddir)/gdk \
+ -I$(top_srcdir)/gtk \
+ -I$(top_builddir)/gtk \
+ -DGDK_DISABLE_DEPRECATED\
+ -DGTK_DISABLE_DEPRECATED
+
+AM_CFLAGS = \
+ $(GTK_DEP_CFLAGS) \
+ $(GTK_DEBUG_FLAGS)
+
+if !OS_WIN32
+libferret_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ ferret.c
+
+libferret_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version \
+ $(no_undefined) \
+ $(LDFLAGS)
+
+libferret_la_LIBADD = \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(GAIL_INET_LIBS)
+endif
+
+libtestaction_la_SOURCES = \
+ testaction.c
+
+libtestaction_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestbutton_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testbutton.c
+
+libtestbutton_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestcombo_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testcombo.c
+
+libtestcombo_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestcomponent_la_SOURCES = \
+ testcomponent.c
+
+libtestcomponent_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestimage_la_SOURCES = \
+ testimage.c
+
+libtestimage_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestmenuitem_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testmenuitem.c
+
+libtestmenuitem_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestnotebook_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testnotebook.c
+
+libtestnotebook_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestobject_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testobject.c
+
+libtestobject_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestpaned_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testpaned.c
+
+libtestpaned_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestprops_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testprops.c
+
+libtestprops_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestselection_la_SOURCES = \
+ testselection.c
+
+libtestselection_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libteststatusbar_la_SOURCES = \
+ teststatusbar.c
+
+libteststatusbar_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtesttable_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testtextlib.c \
+ testtextlib.h \
+ testtable.c
+
+libtesttable_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtesttext_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testtextlib.c \
+ testtextlib.h \
+ testtext.c
+
+libtesttext_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtesttoplevel_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testtoplevel.c
+
+libtesttoplevel_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtesttreetable_la_SOURCES = \
+ testlib.c \
+ testlib.h \
+ testtreetable.c
+
+libtesttreetable_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+libtestvalues_la_SOURCES = \
+ testvalues.c
+
+libtestvalues_la_LDFLAGS = \
+ -rpath $(moduledir) -module -avoid-version $(no_undefined) \
+ $(top_builddir)/gtk/libgtk-3.la \
+ $(top_builddir)/gdk/libgdk-3.la \
+ $(GTK_DEP_LIBS) \
+ $(LDFLAGS)
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+
+============================
+GAIL README
+Last Updated: August 2, 2001
+============================
+
+
+General Info
+============
+
+This README describes how to use the various test programs
+in the gail/tests directory.
+
+To run the various test programs described in this README,
+the test libraries must be built and installed. Running
+"make", then "make install" in the gail top-level directory
+will take care of this. Then do the following:
+
+1. Set the environment variable GTK_MODULES to
+ "libgail:lib<testname>"
+
+ For example, for ferret, it would be "libgail:libferret"
+
+2. Run the GTK+ test program specified. These test programs
+ are found in the GTK+ build directory in the subdirectory
+ called "tests".
+
+Most test programs will display output directly to the
+terminal window where the GTK+ test program was launched.
+Some test programs (testtable and testtext) will launch a
+test GUI program which allows more interactive testing.
+
+The test GUI has two windows. The first window is the
+"Test Control" window and the second window is the
+"Test Output" window. In the "Test Control" window,
+press the button(s) that corresponds to the tests to run
+and press the "Run Tests" button at the bottom of the
+screen. Some tests have associated text entry fields
+which become active when the button is toggled on. These
+text entry fields correspond to arguments that affect how
+the test is executed. They are pre-filled with default
+values but the user can change them if desired. The
+output from the tests is displayed in the "Test Output"
+window.
+
+
+testlib
+=======
+
+Contains general purpose functionality that is used by the
+various tests. These include functions that find a specific
+widget/AtkObject in the test program, and functions used by
+tests that use the Gail Test GUI.
+
+
+ferret
+======
+
+Ferret is a passive in-process test tool for ATK and GAIL.
+
+Run a GTK+-2.0 application such as "testgtk", and ferret will
+display a window on screen. In this window accessibility
+information about the GTK+ widgets will appear as they
+receive focus.
+
+The ferret window has several tabs, one for each of the
+following ATK interfaces.
+
+ Object
+ Action
+ Component
+ Image
+ Table
+ Text
+ Value
+
+Tabs that do not apply to the current widget in focus will be
+displayed as inactive. Clicking on an active tab will display
+information about the AtkObject accessed via the ATK API. In the
+Action tab the various actions are displayed as buttons. When
+a button is clicked, the action specified on the button's
+label is performed.
+
+If you have installed the "festival" speech synthesis system,
+running festival in server mode (festival --server) and turning
+on Ferret's Festival support will cause the following to happen:
+
+1. AtkObject accessible names, roles, and keybindings will be
+ spoken as they receive focus.
+2. When the caret (cursor) is moved in a text field, the
+ current line will be spoken, unless the caret is moved
+ just a single character. In the later case, only the
+ single character after the caret will be spoken.
+
+Festival support can be turned on by checking "Festival" in the
+menu, or by setting the environment variable FERRET_FESTIVAL
+prior to starting the test. By checking "Festival Terse" or
+by setting the environment variable FERRET_TERSE, only the
+name of the AtkObject will be spoken (and not the roles and
+keybindings).
+
+A magnifier can be turned on to enlarge the widget in focus
+by checking "Magnifier" in the menu, or by setting the
+environment variable FERRET_MAGNIFIER. This requires that
+the magnifier standalone code is running.
+
+Checking "Track Mouse in the menu or by setting the environment
+variable FERRET_MOUSETRACK causes ferret to display information
+about the widget that is under the mouse rather than the widget
+that has focus. The mouse is tracked via GtkWidget
+"enter_notify_event" signals, so flyweight objects are not tracked.
+
+Checking "Terminal Output" in the menu or by setting the
+environment variable FERRET_ASCII will display the information
+that is normally displayed to the ferret GUI window to the
+terminal screen.
+
+Checking "No ATK Signals" in the menu or by setting the
+environment variable FERRET_NOSIGNALS will cause ferret to
+ignore any ATK signals, and it will not update its display
+when such signals occur.
+
+
+testaction
+==========
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkAction, except for atk_action_do_action() in the GAIL
+library. It is normally used with the GTK+ test program testgtk.
+
+
+testbutton
+==========
+
+This is a GTK+ module used to test the accessible implementation
+for buttons. It is normally used with the GTK+ test program testgtk.
+
+Set the TEST_ACCESSIBLE_NAME environment variable to have the test
+driver attach to a widget by widget name (compared via the
+gtk_widget_get_name function call).
+
+Set the environment variable TEST_ACCESSIBLE_AUTO and the program
+will execute the action defined for a GailButton once.
+
+
+testcombo
+=========
+
+This is a GTK+ module used to test the implementation of the ATK action
+interfaces on GailCombo. It is normally used with the GTK+ test program
+testgtk by putting the focus in the GtkCombo in entry window.
+
+
+testcomponent
+=============
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkComponent in the GAIL library. It is normally used with the
+GTK+ test program testgtk.
+
+
+testimage
+=========
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkImage in the GAIL library. It is normally used with the GTK+
+test program testgtk, but can also be used with testdnd when you want
+to test GtkPixmap. This modules pops up an extra dialog on startup , containing
+GtkArrows and a GtkImage. This dialog has to be closed before control is returned to main window.
+
+
+testmenuitem
+============
+
+This is a GTK+ module used to test the accessible implementation
+for menu items. It is normally used with the GTK+ test program testgtk.
+
+Set the TEST_ACCESSIBLE_NAME environment variable to have the test
+driver attach to a widget by widget name (compared via the
+gtk_widget_get_name function call).
+
+Set the environment variable TEST_ACCESSIBLE_AUTO and the program
+will execute the action defined for a GailButton once.
+
+
+testnotebook
+=============
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkSelection for GailNotebook. It is normally used with the
+GTK+ test program testgtk.
+
+
+testobject
+==========
+
+This is a GTK+ module used to test the implementation of the ATK
+interface in atkobject.h in the GAIL library. It is normally used with the
+GTK+ test program testgtk.
+
+
+testpaned
+=========
+
+This is a GTK+ module used to test the implementation of the ATK
+interface AtkValue for GailPaned. It is normally used with the
+GTK+ test program testgtk. It checks the setting of the position
+programmatically and that notification is received if the position
+is changed interactively.
+
+
+testprops
+==========
+
+This is a GTK+ module used to test the implementation of ATK properties
+and property change handlers in the GAIL library. It is normally used with
+the GTK+ test program testgtk. To see the changing of the state
+ATK_STATE_SHOWING use menus in "progress bar". To see the changing of the
+state ATK_STATE_SENSITIVE uses "labels". To see changing of child and parent
+use resize check box in "panes".
+
+Set the TEST_ACCESSIBLE_NAME environment variable to have the test
+driver attach to a widget by widget name (compared via the
+gtk_widget_get_name function call).
+
+
+testselection
+=============
+
+This is a GTK+ module used to test the implementation of the AtkSelection
+interface works for the GAIL library. It is normally used with the GTK+
+test program testgtk and clicking on the menus option. It can also be used
+with the GtkCombo which can be accessed by clicking on the entry option.
+
+
+teststatusbar
+=============
+
+This is a GTK+ module used to test that the text on the statusbar
+can be retrieved using GailStatusbar. It is normally used with the GTK+
+test program testgtk and clicking on statusbar button.
+
+
+testtable
+=========
+
+This is GTK+ module used to test the implementation of AtkTable
+interfaces. It can be used with GailTreeView, for example. It
+can be used with any of the following GTK+ test programs:
+testtreecolumns, testtreefocus, testtreesort, testtreeview,
+or treestoretest.
+
+Set the TEST_ACCESSIBLE_NO_PROPERTIES environment variable
+to not receive information about property values changing
+(like cell state changes).
+
+Set the TEST_ACCESSIBLE_NO_GUI environment variable to run the
+test without the GUI program.
+
+
+testtext
+========
+
+This is a GTK+ module used to test the implementation of AtkText and
+AtkEditableText interfaces on GailTextView. It is normally used with
+the GTK+ test program testtext started with a text file loaded.
+It can also be used with the GTK+ test program testgtk, and then
+click on the "entry" or "label" button.
+
+Set the TEST_ACCESSIBLE_NAME environment variable to have the test
+driver attach to a widget by widget name (compared via the
+gtk_widget_get_name function call).
+
+Set the TEST_ACCESSIBLE_DELAY environment variable to an integer
+and the test driver will attach to only a widget on the nth screen
+that is displayed.
+
+
+testtoplevel
+============
+
+This test exercises the AtkUtil functions. It accesses the
+atk_get_root() toplevel object, sets/removes global listeners,
+and displays the ATK implementation name/version.
+
+Set the TEST_ACCESSIBLE_DEPTH environment variable to control
+how deep the children of the toplevel object are displayed.
+The default is a depth of 2. Specifying a depth of -1 will
+show the complete hierarchy.
+
+
+testvalues
+==========
+
+This is a GTK+ module used to test the implementation of AtkValue interface
+works for the GAIL library. GailProgressbar, GailSpinbutton and GailRange
+can all be tested using this module.
+
+
+GAIL README Authors
+===================
+
+-Brian Cameron (brian.cameron@sun.com)
+-Bill Haneman (bill.haneman@sun.com)
+-Padraig O'Briain (padraig.obriain@sun.com)
+
--- /dev/null
+#define MAX_BUFFER 256
+#define MAX_GROUPS 20
+#define MAX_NAME_VALUE 20
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include "testlib.h"
+
+typedef enum
+{
+ OBJECT,
+ ACTION,
+ COMPONENT,
+ IMAGE,
+ SELECTION,
+ TABLE,
+ TEXT,
+ VALUE,
+ END_TABS
+} TabNumber;
+
+typedef enum
+{
+ OBJECT_INTERFACE,
+ RELATION_INTERFACE,
+ STATE_INTERFACE,
+ ACTION_INTERFACE,
+ COMPONENT_INTERFACE,
+ IMAGE_INTERFACE,
+ SELECTION_INTERFACE,
+ TABLE_INTERFACE,
+ TEXT_INTERFACE,
+ TEXT_ATTRIBUTES,
+ VALUE_INTERFACE
+} GroupId;
+
+typedef enum
+{
+ VALUE_STRING,
+ VALUE_BOOLEAN,
+ VALUE_TEXT,
+ VALUE_BUTTON
+} ValueType;
+
+/* GUI Information for the group */
+
+typedef struct
+{
+ GroupId group_id;
+ GtkFrame *scroll_outer_frame;
+ GtkWidget *frame;
+ GtkBox *group_vbox;
+ GtkAdjustment *adj;
+ GList *name_value;
+ gchar *name;
+ gboolean is_scrolled;
+ gint default_height;
+} GroupInfo;
+
+typedef struct
+{
+ GList *groups;
+ GtkWidget *page;
+ GtkWidget *main_box;
+ gchar *name;
+} TabInfo;
+
+typedef struct
+{
+ ValueType type;
+ gboolean active;
+
+ GtkBox *column1, *column2, *hbox;
+ GtkLabel *label;
+
+ GtkButton *button;
+ GValue button_gval;
+ gulong signal_id;
+ AtkObject *atkobj;
+ gint action_num;
+
+ GtkWidget *string;
+ GtkWidget *boolean;
+ GtkWidget *text;
+} NameValue;
+
+typedef enum {
+ FERRET_SIGNAL_OBJECT,
+ FERRET_SIGNAL_TEXT,
+ FERRET_SIGNAL_TABLE
+} FerretSignalType;
+
+/* Function prototypes */
+
+/* GUI functions */
+
+static void _init_data(void);
+static void _create_window(void);
+static void _add_menu(GtkWidget ** menu, GtkWidget ** menuitem,
+ gchar * name, gboolean init_value, GCallback func);
+static void _clear_tab(TabNumber tab_n);
+static void _greyout_tab (GtkWidget *widget, gboolean is_sensitive);
+static void _finished_group(TabNumber tab_n, gint group_num);
+static gboolean _object_is_ours (AtkObject *aobject);
+static void _create_event_watcher (void);
+
+/* Mouse Watcher/Magnifier/Festival functions */
+
+static gboolean _mouse_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static gboolean _button_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+static void _send_to_magnifier (gint x, gint y, gint w, gint h);
+static void _send_to_festival (const gchar * name,
+ const gchar * role_name, const gchar * accel);
+static void _speak_caret_event (AtkObject * aobject);
+static void _festival_say (const gchar * text);
+static void _festival_write (const gchar * text, int fd);
+static gint _festival_init (void);
+
+/* Update functions */
+
+static void _update_current_page(GtkNotebook *notebook, gpointer p,
+ guint current_page);
+static void _update(TabNumber top_tab, AtkObject *aobject);
+
+/* Print functions */
+
+static void _print_accessible (AtkObject *aobject);
+
+static gint _print_object (AtkObject *aobject);
+static gint _print_relation (AtkObject *aobject);
+static gint _print_state (AtkObject *aobject);
+
+static gint _print_action (AtkAction *aobject);
+static gint _print_component (AtkComponent *aobject);
+static gint _print_image (AtkImage *aobject);
+static gint _print_selection (AtkSelection *aobject);
+static gint _print_table (AtkTable *aobject);
+static gint _print_text (AtkText *aobject);
+static gint _print_text_attributes (AtkText *aobject);
+static gint _print_value (AtkValue *aobject);
+static void _print_value_type(gint group_num, gchar *type, GValue *value);
+static gint _print_groupname(TabNumber tab_n, GroupId group_id,
+ const char *groupname);
+static NameValue* _print_key_value(TabNumber tab_n, gint group_number,
+ const char *label, gpointer value, ValueType type);
+static void _print_signal(AtkObject *aobject, FerretSignalType type,
+ const char *name, const char *info);
+
+/* Data Access functions */
+
+static GroupInfo* _get_group(TabInfo *tab, GroupId group_id,
+ const gchar *groupname);
+void _get_group_scrolled(GroupInfo *group);
+static NameValue* _get_name_value(GroupInfo *group, const gchar *label,
+ gpointer value, ValueType type);
+
+/* Signal handlers */
+
+static void _update_handlers(AtkObject *obj);
+static void _notify_text_insert_handler (GObject *obj,
+ int position, int offset);
+static void _notify_text_delete_handler (GObject *obj,
+ int position, int offset);
+static void _notify_caret_handler (GObject *obj, int position);
+static void _notify_table_row_inserted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_column_inserted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_row_deleted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_column_deleted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_row_reordered (GObject *obj);
+static void _notify_table_column_reordered (GObject *obj);
+static void _notify_object_child_added (GObject *obj,
+ gint index, AtkObject *child);
+static void _notify_object_child_removed (GObject *obj,
+ gint index, AtkObject *child);
+static void _notify_object_state_change (GObject *obj,
+ gchar *name, gboolean set);
+
+/* Property handlers */
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+/* Ferret GUI callbacks */
+
+void _action_cb(GtkWidget *widget, gpointer *userdata);
+void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data);
+
+/* Global variables */
+static GtkNotebook *notebook;
+static TabInfo *nbook_tabs[END_TABS];
+static gint mouse_watcher_focus_id = -1;
+static gint mouse_watcher_button_id = -1;
+static gint focus_tracker_id = -1;
+static gboolean use_magnifier = FALSE;
+static gboolean use_festival = FALSE;
+static gboolean track_mouse = FALSE;
+static gboolean track_focus = TRUE;
+static gboolean say_role = TRUE;
+static gboolean say_accel = TRUE;
+static gboolean display_ascii = FALSE;
+static gboolean no_signals = FALSE;
+static gint last_caret_offset = 0;
+
+static AtkObject *last_object = NULL;
+static GtkWidget *mainWindow = NULL;
+static GtkWidget *vbox1 = NULL;
+static GtkWidget *menu = NULL;
+static GtkWidget *menutop = NULL;
+static GtkWidget *menubar = NULL;
+static GtkWidget *menuitem_terminal = NULL;
+static GtkWidget *menuitem_no_signals = NULL;
+static GtkWidget *menuitem_magnifier = NULL;
+static GtkWidget *menuitem_festival = NULL;
+static GtkWidget *menuitem_festival_terse = NULL;
+static GtkWidget *menuitem_trackmouse = NULL;
+static GtkWidget *menuitem_trackfocus = NULL;
+
+#ifdef HAVE_SOCKADDR_UN_SUN_LEN
+static struct sockaddr_un mag_server = { 0, AF_UNIX , "/tmp/magnifier_socket" };
+static struct sockaddr_un client = { 0 , AF_UNIX, "/tmp/mag_client"};
+#else
+static struct sockaddr_un mag_server = { AF_UNIX , "/tmp/magnifier_socket" };
+static struct sockaddr_un client = { AF_UNIX, "/tmp/mag_client"};
+#endif
+
+/* GUI Information for the output window */
+typedef struct
+{
+ GtkWindow *outputWindow;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *textInsert;
+ gchar *testTitle;
+} MainDialog;
+
+static void
+_send_to_magnifier(gint x, gint y, gint w, gint h)
+{
+ int desc;
+ int length_msg G_GNUC_UNUSED;
+ gchar buff[100];
+
+ sprintf (buff, "~5:%d,%d", x+w/2, y+h/2);
+
+#ifdef MAG_DEBUG
+ g_print ("sending magnifier: %s\n", buff);
+#endif
+
+#ifdef HAVE_SOCKADDR_UN_SUN_LEN
+ mag_server.sun_len = SUN_LEN(&mag_server);
+ client.sun_len = SUN_LEN(&client);
+#endif
+
+ if((desc=socket(AF_UNIX,SOCK_STREAM,0)) == -1){
+ perror("socket");
+ return;
+ }
+ unlink("/tmp/mag_client");
+
+ if (bind(desc, (struct sockaddr*)&client, sizeof(client)) == -1)
+ {
+ perror("bind");
+ return;
+ }
+
+ if (connect(desc,(struct sockaddr*)&mag_server,sizeof(mag_server)) == -1)
+ {
+ perror("connect");
+ return;
+ }
+
+ length_msg = write(desc,buff,strlen(buff));
+ unlink("/tmp/mag_client");
+ return;
+}
+
+static int _festival_init (void)
+{
+ int fd;
+ struct sockaddr_in name;
+ int tries = 2;
+
+ name.sin_family = AF_INET;
+ name.sin_port = htons (1314);
+ name.sin_addr.s_addr = htonl(INADDR_ANY);
+ fd = socket (PF_INET, SOCK_STREAM, 0);
+
+ while (connect(fd, (struct sockaddr *) &name, sizeof (name)) < 0) {
+ if (!tries--) {
+ perror ("connect");
+ return -1;
+ }
+ }
+
+ _festival_write ("(audio_mode'async)", fd);
+ return fd;
+}
+
+static void _festival_say (const gchar *text)
+{
+ static int fd = 0;
+ gchar *quoted;
+ gchar *p;
+ gchar prefix [100];
+ const gchar *stretch;
+
+ fprintf (stderr, "saying %s\n", text);
+
+ if (!fd)
+ {
+ fd = _festival_init ();
+ }
+
+ quoted = g_malloc(100+strlen(text)*2);
+
+ stretch = g_strdup (g_getenv ("FESTIVAL_STRETCH"));
+ if (!stretch) stretch = "0.75";
+ sprintf (prefix, "(audio_mode'shutup)\n (Parameter.set 'Duration_Stretch %s)\n (SayText \"", stretch);
+
+ strcpy(quoted, prefix);
+ p = quoted + strlen (prefix);
+ while (*text) {
+ if ( *text == '\\' || *text == '"' )
+ *p = '\\';
+ *p++ = *text++;
+ }
+ *p++ = '"';
+ *p++ = ')';
+ *p = 0;
+
+ _festival_write (quoted, fd);
+
+ g_free(quoted);
+}
+
+
+static void _send_to_festival (const gchar *role_name,
+ const gchar *name, const gchar *accel)
+{
+ gchar *string;
+ int len = (strlen (role_name)+1 + strlen (name)+2 + 4 + strlen (accel)+2);
+ int i, j;
+ gchar ch;
+ gchar *accel_name;
+
+ string = (gchar *) g_malloc (len * sizeof (gchar));
+
+ i = 0;
+ if (say_role)
+ {
+ j = 0;
+ while (role_name[j])
+ {
+ ch = role_name[j++];
+ if (ch == '_') ch = ' ';
+ string[i++] = ch;
+ };
+ string[i++] = ' ';
+ }
+ j = 0;
+ while (name[j])
+ {
+ ch = name[j++];
+ if (ch == '_') ch = ' ';
+ string[i++] = ch;
+ };
+ if ((say_accel) && (strlen (accel) > 0))
+ {
+ accel_name = (gchar *)accel;
+ if (strncmp (accel, "<C", 2) == 0)
+ {
+ accel_name = strncpy (accel_name, " control ", 9);
+ }
+ else if (strncmp (accel, " control", 5))
+ {
+ string[i++] = ' ';
+ string[i++] = 'a';
+ string[i++] = 'l';
+ string[i++] = 't';
+ string[i++] = ' ';
+ }
+ j = 0;
+ while (accel_name[j])
+ {
+ ch = accel_name[j++];
+ if (ch == '_') ch = ' ';
+ string[i++] = ch;
+ };
+ }
+ string[i] = '\0';
+
+ _festival_say (string);
+ g_free (string);
+}
+
+static void _festival_write (const gchar *command_string, int fd)
+{
+ gssize n_bytes;
+
+ if (fd < 0) {
+ perror("socket");
+ return;
+ }
+ n_bytes = write(fd, command_string, strlen(command_string));
+ g_assert (n_bytes == strlen(command_string));
+}
+
+static void _speak_caret_event (AtkObject *aobject)
+{
+ gint dummy1, dummy2;
+ gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
+ gchar * text;
+
+ if (abs(caret_offset - last_caret_offset) > 1)
+ {
+ text = atk_text_get_text_at_offset (ATK_TEXT (aobject),
+ caret_offset,
+ ATK_TEXT_BOUNDARY_LINE_START,
+ &dummy1,
+ &dummy2);
+ }
+ else
+ {
+ text = atk_text_get_text_before_offset (ATK_TEXT (aobject),
+ caret_offset,
+ ATK_TEXT_BOUNDARY_CHAR,
+ &dummy1,
+ &dummy2);
+ }
+ _festival_say (text);
+ g_free (text);
+ last_caret_offset = caret_offset;
+}
+
+static void
+_greyout_tab (GtkWidget *page_child, gboolean is_sensitive)
+{
+ GtkWidget *tab;
+
+ tab = gtk_notebook_get_tab_label (notebook, page_child);
+ if (tab)
+ gtk_widget_set_sensitive (GTK_WIDGET (tab), is_sensitive);
+}
+
+static void
+_refresh_notebook (AtkObject *aobject)
+{
+ if (ATK_IS_OBJECT (aobject))
+ {
+ _greyout_tab (nbook_tabs[ACTION]->page, ATK_IS_ACTION(aobject));
+ _greyout_tab (nbook_tabs[COMPONENT]->page, ATK_IS_COMPONENT(aobject));
+ _greyout_tab (nbook_tabs[IMAGE]->page, ATK_IS_IMAGE(aobject));
+ _greyout_tab (nbook_tabs[SELECTION]->page, ATK_IS_SELECTION(aobject));
+ _greyout_tab (nbook_tabs[TABLE]->page, ATK_IS_TABLE(aobject));
+ _greyout_tab (nbook_tabs[TEXT]->page, ATK_IS_TEXT(aobject));
+ _greyout_tab (nbook_tabs[VALUE]->page, ATK_IS_VALUE(aobject));
+ }
+}
+
+static void _print_accessible (AtkObject *aobject)
+{
+ TabNumber top_tab;
+
+ if (_object_is_ours(aobject))
+ {
+ if (display_ascii)
+ g_print("\nFocus entered the ferret output window!\n");
+ return;
+ }
+
+ _refresh_notebook(aobject);
+
+ if (display_ascii)
+ g_print("\nFocus change\n");
+
+ /* Do not attach signal handlers if the user has asked not to */
+ if (!no_signals)
+ _update_handlers(aobject);
+ else
+ last_object = aobject; /* _update_handler normally does this */
+
+ top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
+ _update(top_tab, aobject);
+
+ if (use_magnifier)
+ {
+ gint x, y;
+ gint w=0, h=0;
+
+ if (ATK_IS_TEXT (aobject))
+ {
+ gint x0, y0, w0, h0;
+ gint xN, yN, wN, hN;
+ gint len;
+ len = atk_text_get_character_count (ATK_TEXT (aobject));
+ atk_text_get_character_extents (ATK_TEXT (aobject), 0,
+ &x0, &y0, &w0, &h0,
+ ATK_XY_SCREEN);
+ if (len > 0)
+ {
+ atk_text_get_character_extents (ATK_TEXT (aobject), len-1,
+ &xN, &yN, &wN, &hN,
+ ATK_XY_SCREEN);
+ x = MIN (x0, xN);
+ y = MIN (y0, yN);
+ w = MAX (x0+w0, xN+wN) - x;
+ h = MAX (y0+h0, yN+hN) - y;
+ }
+ else
+ {
+ x = x0;
+ y = y0;
+ }
+ }
+ else if (ATK_IS_COMPONENT (aobject))
+ {
+ atk_component_get_extents (ATK_COMPONENT(aobject),
+ &x, &y, &w, &h,
+ ATK_XY_SCREEN);
+ }
+ if (w > -1) _send_to_magnifier (x, y, w, h);
+ }
+}
+
+static gboolean
+_object_is_ours (AtkObject *aobject)
+{
+ /* determine whether this object is parented by our own accessible... */
+
+ AtkObject *toplevel = aobject;
+
+ while (atk_object_get_role(aobject) != ATK_ROLE_FRAME)
+ {
+ aobject = atk_object_get_parent (aobject);
+ if (aobject == NULL) break;
+ toplevel = aobject;
+ };
+
+ /*
+ * Some widgets do not have an ATK_ROLE_FRAME at the top,
+ * so ignore those.
+ */
+ if (aobject != NULL)
+ {
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (toplevel));
+ if (widget == mainWindow)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gchar *
+ferret_get_name_from_container (AtkObject *aobject)
+{
+ gchar *s = NULL;
+ gint n = atk_object_get_n_accessible_children (aobject);
+ gint i = 0;
+
+ while (!s && (i < n))
+ {
+ AtkObject *child;
+ child = atk_object_ref_accessible_child (aobject, i);
+ if (ATK_IS_TEXT (child))
+ {
+ gint count = atk_text_get_character_count (ATK_TEXT (child));
+ s = atk_text_get_text (ATK_TEXT (child),
+ 0,
+ count);
+ }
+ g_object_unref (child);
+ ++i;
+ }
+
+ if (!s)
+ {
+ s = g_strdup ("");
+ }
+ return s;
+}
+
+static gint
+_print_object (AtkObject *aobject)
+{
+ GtkWidget *widget;
+ const gchar * parent_name = NULL;
+ const gchar * name = NULL;
+ const gchar * description = NULL;
+ const gchar * typename = NULL;
+ const gchar * parent_typename = NULL;
+ const gchar * role_name = NULL;
+ const gchar * accel_name = NULL;
+ const gchar * text = NULL;
+ AtkRole role;
+ AtkObject *parent = NULL;
+ static AtkObject *prev_aobject = NULL;
+ gint n_children = 0;
+ gint index_in_parent = -1;
+ gchar *output_str;
+ gint group_num;
+ TabNumber tab_n = OBJECT;
+
+ group_num = _print_groupname(tab_n, OBJECT_INTERFACE, "Object Interface");
+
+ name = atk_object_get_name (aobject);
+ typename = g_type_name (G_OBJECT_TYPE (aobject));
+ description = atk_object_get_description (aobject);
+ parent = atk_object_get_parent(aobject);
+ if (parent)
+ index_in_parent = atk_object_get_index_in_parent(aobject);
+ n_children = atk_object_get_n_accessible_children(aobject);
+ role = atk_object_get_role(aobject);
+ role_name = atk_role_get_name(role);
+
+ if (ATK_IS_ACTION (aobject))
+ {
+ accel_name = atk_action_get_keybinding (ATK_ACTION(aobject), 0);
+ if (!accel_name) accel_name = "";
+ }
+ else
+ {
+ accel_name = "";
+ }
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (aobject));
+ if (widget)
+ {
+ _print_key_value(tab_n, group_num, "Widget name",
+ (gpointer)gtk_widget_get_name (widget),
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Widget name", "No Widget",
+ VALUE_STRING);
+ }
+
+ if (typename)
+ {
+ _print_key_value(tab_n, group_num, "Accessible Type",
+ (gpointer)typename, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Accessible Type", "NULL",
+ VALUE_STRING);
+ }
+
+ if (name)
+ {
+ _print_key_value(tab_n, group_num, "Accessible Name",
+ (gpointer)name, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Accessible Name", "(unknown)",
+ VALUE_STRING);
+ }
+ if (use_festival)
+ {
+ if (aobject != prev_aobject)
+ {
+ if (ATK_IS_TEXT (aobject) && !name)
+ {
+ text =
+ atk_text_get_text_at_offset (ATK_TEXT (aobject),
+ (gint) 0,
+ ATK_TEXT_BOUNDARY_SENTENCE_END,
+ (gint *) NULL,
+ (gint *) NULL);
+ fprintf (stderr, "first sentence: %s\n", text);
+ _send_to_festival (role_name,
+ text, "");
+ if (!name) name = "no name";
+ }
+ else
+ {
+ text = "";
+ if (!name)
+ {
+ if (atk_object_get_role (aobject) == ATK_ROLE_TABLE_CELL)
+ {
+ gchar *cname = ferret_get_name_from_container (aobject);
+ if (cname) name = g_strdup (cname);
+ }
+ else if (atk_object_get_role (aobject) == ATK_ROLE_CHECK_BOX)
+ {
+ name = g_strdup ("check box");
+ }
+ else
+ {
+ name = "no name";
+ }
+ }
+ _send_to_festival (role_name, name, accel_name);
+ }
+ }
+ }
+
+ if (parent)
+ {
+ parent_name = atk_object_get_name(parent);
+
+ parent_typename = g_type_name (G_OBJECT_TYPE (parent));
+
+ if (parent_typename)
+ {
+ _print_key_value(tab_n, group_num, "Parent Accessible Type",
+ (gpointer)parent_typename, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num,
+ "Parent Accessible Type", "NULL", VALUE_STRING);
+ }
+
+ if (parent_name)
+ {
+ _print_key_value(tab_n, group_num, "Parent Accessible Name",
+ (gpointer)parent_name, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num,
+ "Parent Accessible Name", "NULL", VALUE_STRING);
+ }
+
+ output_str = g_strdup_printf("%d", index_in_parent);
+ _print_key_value(tab_n, group_num, "Index in Parent",
+ (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Parent", "NULL", VALUE_STRING);
+ }
+
+ if (description)
+ {
+ _print_key_value(tab_n, group_num, "Accessible Description",
+ (gpointer)description, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num,
+ "Accessible Description", "NULL", VALUE_STRING);
+ }
+
+ if (role_name)
+ {
+ _print_key_value(tab_n, group_num, "Accessible Role", (gpointer)role_name,
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Accessible Role", "NULL",
+ VALUE_STRING);
+ }
+
+ output_str = g_strdup_printf("%d", n_children);
+ _print_key_value(tab_n, group_num, "Number Children", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+ prev_aobject = aobject;
+
+ return(group_num);
+}
+
+static gint
+_print_relation (AtkObject *aobject)
+{
+ AtkRelationSet* relation_set = atk_object_ref_relation_set (aobject);
+ gint n_relations = atk_relation_set_get_n_relations (relation_set);
+ gint group_num;
+ TabNumber tab_n = OBJECT;
+
+ group_num = _print_groupname(tab_n, RELATION_INTERFACE,
+ "Relation Interface");
+
+ if (relation_set)
+ {
+ AtkRelation * relation;
+ const gchar * relation_name = NULL;
+ const gchar * relation_obj_name = NULL;
+ AtkRelationType relation_type;
+ AtkObject *relation_obj;
+ GPtrArray * relation_arry;
+ gchar *label_str;
+ gchar *output_str;
+ gint i, j;
+
+ output_str = g_strdup_printf("%d", n_relations);
+ _print_key_value(tab_n, group_num,
+ "Number of Relations", (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+
+ for (i = 0; i < n_relations; i++)
+ {
+ relation = atk_relation_set_get_relation (relation_set, i);
+
+ relation_type = atk_relation_get_relation_type (relation);
+ relation_name = atk_relation_type_get_name (relation_type);
+
+ relation_arry = atk_relation_get_target(relation);
+
+ if (relation_name)
+ {
+ label_str = g_strdup_printf("Relation %d Name", i + 1);
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)relation_name, VALUE_STRING);
+ g_free(label_str);
+ }
+ else
+ {
+ label_str = g_strdup_printf("Relation %d Type", i + 1);
+ output_str = g_strdup_printf("%d", relation_type);
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)output_str, VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+ }
+
+ label_str = g_strdup_printf("Relation %d with", i + 1);
+ output_str = g_strdup_printf("%d AtkObjects", relation_arry->len);
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+
+ for (j=0; j < relation_arry->len; j++)
+ {
+ label_str = g_strdup_printf(
+ "Relation %d,%d with AtkObject Name", i + 1, j + 1);
+ relation_obj = (AtkObject *)
+ g_ptr_array_index(relation_arry, j);
+ relation_obj_name = atk_object_get_name(relation_obj);
+
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)relation_obj_name, VALUE_STRING);
+ g_free(label_str);
+ }
+ }
+
+ g_object_unref (relation_set);
+ }
+ return(group_num);
+}
+
+static gint
+_print_state (AtkObject *aobject)
+{
+ AtkStateSet *state_set = atk_object_ref_state_set(aobject);
+ gint group_num;
+ TabNumber tab_n = OBJECT;
+ static AtkStateType states_to_track[] =
+ {
+ ATK_STATE_ACTIVE,
+ ATK_STATE_CHECKED,
+ ATK_STATE_EXPANDED,
+ ATK_STATE_EXPANDABLE,
+ ATK_STATE_SELECTED,
+ ATK_STATE_SHOWING,
+ ATK_STATE_VISIBLE
+ };
+
+ group_num = _print_groupname(tab_n, STATE_INTERFACE,
+ "State Interface");
+
+ if (state_set)
+ {
+ gboolean boolean_value;
+ AtkStateType one_state;
+ const gchar *name;
+ gint i;
+
+ for (i=0; i < sizeof(states_to_track)/sizeof(AtkStateType); i++)
+ {
+ one_state = (AtkStateType) states_to_track[i];
+ name = atk_state_type_get_name (one_state);
+
+ if (name)
+ {
+ boolean_value =
+ atk_state_set_contains_state (state_set, one_state);
+ _print_key_value(tab_n, group_num, name,
+ (gpointer)(&boolean_value), VALUE_BOOLEAN);
+ }
+ }
+ }
+
+ g_object_unref (state_set);
+ return(group_num);
+}
+
+static gint
+_print_action (AtkAction *aobject)
+{
+ const gchar *action_name;
+ const gchar *action_description;
+ const gchar *action_keybinding;
+ gchar *label_str, *output_str;
+ gint group_num;
+ gint num_actions, j;
+ TabNumber tab_n = ACTION;
+ NameValue *nv;
+
+ group_num = _print_groupname(tab_n, ACTION_INTERFACE,
+ "Action Interface");
+
+ num_actions = atk_action_get_n_actions (aobject);
+ output_str = g_strdup_printf("%d", num_actions);
+ _print_key_value(tab_n, group_num, "Number of Actions",
+ (gpointer) output_str, VALUE_STRING);
+ g_free(output_str);
+
+ for (j = 0; j < num_actions; j++)
+ {
+ label_str = g_strdup_printf("Action %d Name", j + 1);
+ action_name = atk_action_get_name (aobject, j);
+ if (action_name)
+ {
+ nv = _print_key_value(tab_n, group_num, label_str,
+ (gpointer) action_name, VALUE_BUTTON);
+ }
+ else
+ {
+ nv = _print_key_value(tab_n, group_num, label_str, "NULL",
+ VALUE_BUTTON);
+ }
+
+ nv->atkobj = ATK_OBJECT(aobject);
+ nv->action_num = j;
+ nv->signal_id = g_signal_connect (nv->button,
+ "clicked", G_CALLBACK (_action_cb), nv);
+
+ g_free(label_str);
+
+ label_str = g_strdup_printf("Action %d Description", j + 1);
+ action_description = atk_action_get_description (aobject, j);
+ if (action_description)
+ {
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)action_description, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, label_str, "NULL",
+ VALUE_STRING);
+ }
+ g_free(label_str);
+
+ label_str = g_strdup_printf("Action %d Keybinding", j + 1);
+ action_keybinding = atk_action_get_keybinding (aobject, j);
+ if (action_keybinding)
+ {
+ _print_key_value(tab_n, group_num, label_str,
+ (gpointer)action_keybinding, VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, label_str, "NULL",
+ VALUE_STRING);
+ }
+ g_free(label_str);
+ }
+ return(group_num);
+}
+
+static gint
+_print_component (AtkComponent *aobject)
+{
+ gchar *output_str;
+ gint x = 0;
+ gint y = 0;
+ gint width = 0;
+ gint height = 0;
+ gint group_num;
+ TabNumber tab_n = COMPONENT;
+
+ group_num = _print_groupname(tab_n, COMPONENT_INTERFACE,
+ "Component Interface");
+
+ atk_component_get_extents (aobject,
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+
+ output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
+ x, y, width, height);
+ _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+ return(group_num);
+}
+
+static gint
+_print_image (AtkImage *aobject)
+{
+ const gchar *image_desc;
+ gchar *output_str;
+ gint x = 0;
+ gint y = 0;
+ gint height = 0;
+ gint width = 0;
+ gint group_num;
+ TabNumber tab_n = IMAGE;
+
+ group_num = _print_groupname(tab_n, IMAGE_INTERFACE,
+ "Image Interface");
+
+ image_desc = atk_image_get_image_description(aobject);
+ if (image_desc)
+ {
+ _print_key_value(tab_n, group_num, "Description", (gpointer)image_desc,
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Description", "NULL",
+ VALUE_STRING);
+ }
+
+ atk_image_get_image_position(aobject, &x, &y, ATK_XY_SCREEN);
+ atk_image_get_image_size(aobject, &height, &width);
+
+ output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
+ x, y, width, height);
+ _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+ return(group_num);
+}
+
+static gint
+_print_selection (AtkSelection *aobject)
+{
+ AtkObject *object;
+ AtkRole role;
+ gchar *label_str, *output_str;
+ gint group_num;
+ gint n_selected, j, n_selectable;
+ TabNumber tab_n = SELECTION;
+
+ group_num = _print_groupname(tab_n, SELECTION_INTERFACE,
+ "Selection Interface");
+
+ n_selected = atk_selection_get_selection_count (aobject);
+ output_str = g_strdup_printf ("%d", n_selected);
+ _print_key_value (tab_n, group_num, "Number of Selected Children",
+ (gpointer) output_str, VALUE_STRING);
+ g_free (output_str);
+ /*
+ * The number of selected items is the number of children except for
+ * a ComboBox where it is the number of items in the list.
+ */
+ object = ATK_OBJECT (aobject);
+ role = atk_object_get_role (object);
+ if (role == ATK_ROLE_COMBO_BOX)
+ {
+ object = atk_object_ref_accessible_child (object, 0);
+ g_return_val_if_fail (atk_object_get_role (object) == ATK_ROLE_LIST,
+ group_num);
+ n_selectable = atk_object_get_n_accessible_children (object);
+ g_object_unref (G_OBJECT (object));
+ }
+ else
+ {
+ n_selectable = atk_object_get_n_accessible_children (object);
+ }
+ output_str = g_strdup_printf ("%d", n_selectable);
+ _print_key_value (tab_n, group_num, "Number of Selectable Children",
+ (gpointer) output_str, VALUE_STRING);
+ g_free (output_str);
+
+ for (j = 0; j < n_selected; j++)
+ {
+ const gchar *selected_name;
+ AtkObject *selected_object;
+
+ selected_object = atk_selection_ref_selection (aobject, j);
+ selected_name = atk_object_get_name (selected_object);
+ if (selected_name == NULL)
+ {
+ selected_name = "No name";
+ }
+ label_str = g_strdup_printf ("Selected item: %d Name", j+1);
+ _print_key_value (tab_n, group_num, label_str,
+ (gpointer) selected_name, VALUE_STRING);
+ g_free (label_str);
+ g_object_unref (G_OBJECT (selected_object));
+ }
+ return group_num;
+}
+
+static gint
+_print_table (AtkTable *aobject)
+{
+ gchar *label_str, *output_str;
+ const gchar *col_desc;
+ AtkObject *caption;
+ gint n_cols, n_rows;
+ gint i;
+ gint group_num;
+ TabNumber tab_n = TABLE;
+
+ group_num = _print_groupname(tab_n, TABLE_INTERFACE,
+ "Table Interface");
+
+ n_cols = atk_table_get_n_columns(aobject);
+ output_str = g_strdup_printf("%d", n_cols);
+ _print_key_value(tab_n, group_num, "Number Columns", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+
+ n_rows = atk_table_get_n_rows(aobject);
+ output_str = g_strdup_printf("%d", n_rows);
+ _print_key_value(tab_n, group_num, "Number Rows", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+
+ caption = atk_table_get_caption(aobject);
+ if (caption)
+ {
+ const gchar* caption_name;
+
+ caption_name = atk_object_get_name (caption);
+ if (caption_name)
+ {
+ _print_key_value(tab_n, group_num, "Caption Name",
+ (gpointer)caption_name, VALUE_STRING);
+ }
+ }
+
+ for (i=0; i < n_cols; i++)
+ {
+ label_str = g_strdup_printf("Column %d Description", i + 1);
+
+ col_desc = atk_table_get_column_description(aobject, i);
+ if (col_desc)
+ {
+ _print_key_value(tab_n, group_num, label_str, (gpointer)col_desc,
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, label_str, "NULL",
+ VALUE_STRING);
+ }
+
+ g_free(label_str);
+ }
+
+ return(group_num);
+}
+
+static gint
+_print_text (AtkText *aobject)
+{
+ gchar *output_str, *text_val, *text_val_escaped;
+ gint n_chars, caret_offset;
+ gint start_offset, end_offset;
+ gint group_num;
+ gint x, y, w, h;
+ TabNumber tab_n = TEXT;
+
+ group_num = _print_groupname(tab_n, TEXT_INTERFACE,
+ "Text Content");
+
+ n_chars = atk_text_get_character_count(aobject);
+
+ output_str = g_strdup_printf("%d", n_chars);
+ _print_key_value(tab_n, group_num, "Total Character Count",
+ (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+
+ /*
+ * Pass through g_strescape so that non-ASCII chars are made
+ * print-able.
+ */
+ text_val = atk_text_get_text (aobject, 0, n_chars);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value (tab_n, group_num, "Text", (gpointer)text_val_escaped,
+ VALUE_TEXT);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value (tab_n, group_num, "Text", "NULL", VALUE_TEXT);
+ }
+
+ caret_offset = atk_text_get_caret_offset(aobject);
+ output_str = g_strdup_printf("%d", caret_offset);
+ _print_key_value(tab_n, group_num, "Caret Offset", (gpointer)output_str,
+ VALUE_STRING);
+ g_free(output_str);
+
+ if (caret_offset < 0)
+ return(group_num);
+
+ text_val = atk_text_get_text_at_offset (aobject, caret_offset,
+ ATK_TEXT_BOUNDARY_CHAR,
+ &start_offset, &end_offset);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value(tab_n, group_num, "Current Character",
+ (gpointer)text_val_escaped, VALUE_STRING);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Current Character", "none",
+ VALUE_STRING);
+ }
+
+ atk_text_get_character_extents (aobject, caret_offset,
+ &x, &y, &w, &h, ATK_XY_SCREEN);
+ output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
+ if (output_str)
+ {
+ _print_key_value(tab_n, group_num, "Character Bounds (screen)",
+ (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+ }
+
+ atk_text_get_character_extents (aobject, caret_offset,
+ &x, &y, &w, &h, ATK_XY_WINDOW);
+ output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
+ if (output_str)
+ {
+ _print_key_value(tab_n, group_num, "Character Bounds (window)",
+ (gpointer)output_str, VALUE_STRING);
+ g_free(output_str);
+ }
+
+ text_val = atk_text_get_text_at_offset (aobject, caret_offset,
+ ATK_TEXT_BOUNDARY_WORD_START,
+ &start_offset, &end_offset);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value(tab_n, group_num, "Current Word",
+ (gpointer)text_val_escaped, VALUE_STRING);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Current Word", "none",
+ VALUE_STRING);
+ }
+
+ text_val = atk_text_get_text_at_offset (aobject, caret_offset,
+ ATK_TEXT_BOUNDARY_LINE_START,
+ &start_offset, &end_offset);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value(tab_n, group_num, "Current Line",
+ (gpointer)text_val_escaped, VALUE_STRING);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Current Line", "none",
+ VALUE_STRING);
+ }
+
+ text_val = atk_text_get_text_at_offset (aobject, caret_offset,
+ ATK_TEXT_BOUNDARY_SENTENCE_START,
+ &start_offset, &end_offset);
+ if (text_val)
+ {
+ text_val_escaped = g_strescape(text_val, NULL);
+ _print_key_value(tab_n, group_num, "Current Sentence",
+ (gpointer)text_val_escaped, VALUE_STRING);
+ g_free (text_val);
+ g_free (text_val_escaped);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Current Line", "none",
+ VALUE_STRING);
+ }
+ return(group_num);
+}
+
+static gint
+_print_text_attributes (AtkText *aobject)
+{
+ AtkAttributeSet *attribute_set;
+ AtkAttribute *attribute;
+ gchar *output_str, *label_str;
+ gint start_offset, end_offset, caret_offset;
+ gint attribute_set_len, attribute_offset, i;
+ gint group_num;
+ TabNumber tab_n = TEXT;
+
+ group_num = _print_groupname (tab_n, TEXT_ATTRIBUTES,
+ "Text Attributes at Caret");
+
+ caret_offset = atk_text_get_caret_offset(aobject);
+ attribute_offset = caret_offset;
+
+ start_offset = 0;
+ end_offset = 0;
+
+ attribute_set = atk_text_get_run_attributes(aobject, attribute_offset,
+ &start_offset, &end_offset);
+
+ label_str = g_strdup_printf("Attribute run start");
+
+ output_str = g_strdup_printf("%d", start_offset);
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+
+ label_str = g_strdup_printf("Attribute run end");
+ output_str = g_strdup_printf("%d", end_offset);
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+
+ if (attribute_set == NULL)
+ attribute_set_len = 0;
+ else
+ attribute_set_len = g_slist_length(attribute_set);
+
+ label_str = g_strdup_printf("Number of Attributes");
+ output_str = g_strdup_printf("%d", attribute_set_len);
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ g_free(label_str);
+ g_free(output_str);
+
+ for (i=0; i < attribute_set_len; i++)
+ {
+ attribute = ((AtkAttribute *) g_slist_nth(attribute_set, i)->data);
+
+ _print_key_value(tab_n, group_num, attribute->name,
+ (gpointer)attribute->value, VALUE_STRING);
+ }
+ if (attribute_set != NULL)
+ atk_attribute_set_free(attribute_set);
+
+
+ return(group_num);
+}
+
+static gint
+_print_value (AtkValue *aobject)
+{
+ GValue *value_back, val;
+ gint group_num;
+ TabNumber tab_n = VALUE;
+
+ value_back = &val;
+
+ group_num = _print_groupname(tab_n, VALUE_INTERFACE,
+ "Value Interface");
+
+ atk_value_get_current_value(aobject, value_back);
+ _print_value_type(group_num, "Value", value_back);
+ atk_value_get_minimum_value(aobject, value_back);
+ _print_value_type(group_num, "Minimum Value", value_back);
+ atk_value_get_maximum_value(aobject, value_back);
+ _print_value_type(group_num, "Maximum Value", value_back);
+ return(group_num);
+}
+
+static void
+_print_value_type(gint group_num, gchar *type, GValue *value)
+{
+ gchar *label_str = NULL;
+ gchar *output_str = NULL;
+ TabNumber tab_n = VALUE;
+
+ if (G_VALUE_HOLDS_DOUBLE (value))
+ {
+ label_str = g_strdup_printf("%s - Double", type);
+ output_str = g_strdup_printf("%f",
+ g_value_get_double (value));
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ }
+ else if (G_VALUE_HOLDS_INT (value))
+ {
+ label_str = g_strdup_printf("%s - Integer", type);
+ output_str = g_strdup_printf("%d",
+ g_value_get_int (value));
+ _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
+ VALUE_STRING);
+ }
+ else
+ {
+ _print_key_value(tab_n, group_num, "Value", "Unknown Type",
+ VALUE_STRING);
+ }
+
+ if (label_str)
+ g_free(label_str);
+ if (output_str)
+ g_free(output_str);
+}
+
+static void
+_create_event_watcher (void)
+{
+ focus_tracker_id = atk_add_focus_tracker (_print_accessible);
+
+ if (track_mouse)
+ {
+ mouse_watcher_focus_id =
+ atk_add_global_event_listener(_mouse_watcher,
+ "Gtk:GtkWidget:enter_notify_event");
+ mouse_watcher_button_id =
+ atk_add_global_event_listener(_button_watcher,
+ "Gtk:GtkWidget:button_press_event");
+ }
+}
+
+static gboolean
+_mouse_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+
+ object = g_value_get_object (param_values + 0);
+
+ if (GTK_IS_MENU(object)) return TRUE;
+
+ g_assert (GTK_IS_WIDGET(object));
+
+ widget = GTK_WIDGET (object);
+ if (GTK_IS_WINDOW (widget))
+ {
+ GtkWidget *focus_widget = gtk_window_get_focus (GTK_WINDOW (widget));
+ if (focus_widget != NULL)
+ widget = focus_widget;
+ }
+
+ _print_accessible (gtk_widget_get_accessible (widget));
+ return TRUE;
+}
+
+static gboolean
+_button_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GtkWidget *widget;
+
+ object = g_value_get_object (param_values + 0);
+
+ widget = GTK_WIDGET (object);
+ if (GTK_IS_CONTAINER (widget))
+ {
+ if (G_VALUE_HOLDS_BOXED (param_values + 1))
+ {
+ GdkEventButton *event;
+ gpointer gp;
+ AtkObject *aobject;
+ AtkObject *child;
+ gint aobject_x, aobject_y;
+ gint x, y;
+
+ gp = g_value_get_boxed (param_values + 1);
+ event = (GdkEventButton *) gp;
+ aobject = gtk_widget_get_accessible (widget);
+ aobject_x = aobject_y = 0;
+ atk_component_get_position (ATK_COMPONENT (aobject),
+ &aobject_x, &aobject_y,
+ ATK_XY_WINDOW);
+ x = aobject_x + (gint) event->x;
+ y = aobject_y + (gint) event->y;
+ child = atk_component_ref_accessible_at_point (ATK_COMPONENT (aobject),
+ x,
+ y,
+ ATK_XY_WINDOW);
+ if (child)
+ {
+ _print_accessible (child);
+ g_object_unref (child);
+ }
+ else
+ {
+ if (!GTK_IS_MENU_ITEM (widget))
+ {
+ g_print ("No child at position %d %d for %s\n",
+ x,
+ y,
+ g_type_name (G_OBJECT_TYPE (widget)));
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static void _add_notebook_page (GtkNotebook *nbook,
+ GtkWidget *content_widget,
+ GtkWidget **new_page,
+ const gchar *label_text)
+{
+ GtkWidget *label;
+
+ if (content_widget != NULL)
+ {
+ *new_page = content_widget;
+ }
+ else
+ {
+ *new_page = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
+ }
+
+ label = gtk_label_new ("");
+ gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), label_text);
+ gtk_notebook_append_page (notebook, *new_page, label);
+ gtk_widget_show(*new_page);
+}
+
+static void
+_create_notebook (void)
+{
+ TabInfo *tab;
+ notebook = GTK_NOTEBOOK (gtk_notebook_new());
+
+ tab = nbook_tabs[OBJECT];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Object</b>");
+
+ tab = nbook_tabs[ACTION];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Action</b>");
+
+ tab = nbook_tabs[COMPONENT];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Component</b>");
+
+ tab = nbook_tabs[IMAGE];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Image</b>");
+
+ tab = nbook_tabs[SELECTION];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Selection</b>");
+
+ tab = nbook_tabs[TABLE];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Table</b>");
+
+ tab = nbook_tabs[TEXT];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>Te_xt</b>");
+
+ tab = nbook_tabs[VALUE];
+ _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Value</b>");
+
+ g_signal_connect (notebook,
+ "switch-page",
+ G_CALLBACK (_update_current_page),
+ NULL);
+}
+
+static void
+_init_data(void)
+{
+ TabInfo *the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
+ the_tab->name = "Object";
+ nbook_tabs[OBJECT] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
+ the_tab->name = "Action";
+ nbook_tabs[ACTION] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
+ the_tab->name = "Component";
+ nbook_tabs[COMPONENT] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
+ the_tab->name = "Image";
+ nbook_tabs[IMAGE] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
+ the_tab->name = "Selection";
+ nbook_tabs[SELECTION] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
+ the_tab->name = "Table";
+ nbook_tabs[TABLE] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
+ the_tab->name = "Text";
+ nbook_tabs[TEXT] = the_tab;
+
+ the_tab = g_new0(TabInfo, 1);
+ the_tab->page = NULL;
+ the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
+ the_tab->name = "Value";
+ nbook_tabs[VALUE] = the_tab;
+}
+
+static void
+_create_window (void)
+{
+ static GtkWidget *window = NULL;
+
+ if (!window)
+ {
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_name (window, "Ferret Window");
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &window);
+
+ gtk_window_set_title (GTK_WINDOW (window), "GTK+ Ferret Output");
+ gtk_window_set_default_size (GTK_WINDOW (window), 333, 550);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 0);
+
+ vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_add (GTK_CONTAINER (window), vbox1);
+ gtk_widget_show (vbox1);
+
+ menubar = gtk_menu_bar_new ();
+ gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, TRUE, 0);
+ gtk_widget_show (menubar);
+ menutop = gtk_menu_item_new_with_label("Menu");
+ gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menutop);
+ gtk_widget_show (menutop);
+ menu = gtk_menu_new();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menutop), menu);
+ gtk_widget_show (menu);
+
+ _add_menu(&menu, &menuitem_trackmouse, "Track Mouse", track_mouse,
+ G_CALLBACK(_toggle_trackmouse));
+ _add_menu(&menu, &menuitem_trackfocus, "Track Focus", track_focus,
+ G_CALLBACK(_toggle_trackfocus));
+ _add_menu(&menu, &menuitem_magnifier, "Magnifier", use_magnifier,
+ G_CALLBACK(_toggle_magnifier));
+ _add_menu(&menu, &menuitem_festival, "Festival", use_festival,
+ G_CALLBACK(_toggle_festival));
+ _add_menu(&menu, &menuitem_festival_terse, "Festival Terse",
+ (!say_role && !say_accel),
+ G_CALLBACK(_toggle_festival_terse));
+ _add_menu(&menu, &menuitem_terminal, "Terminal Output", display_ascii,
+ G_CALLBACK(_toggle_terminal));
+ _add_menu(&menu, &menuitem_no_signals, "No ATK Signals", no_signals,
+ G_CALLBACK(_toggle_no_signals));
+
+ _create_notebook ();
+ gtk_container_add (GTK_CONTAINER (vbox1), GTK_WIDGET (notebook));
+ gtk_widget_show (GTK_WIDGET (notebook));
+ }
+ if (!gtk_widget_get_visible (window))
+ gtk_widget_show (window);
+
+ mainWindow = GTK_WIDGET (window);
+}
+
+static void
+_add_menu(GtkWidget ** menu, GtkWidget ** menuitem, gchar * name,
+ gboolean init_value, GCallback func)
+{
+ *menuitem = gtk_check_menu_item_new_with_label(name);
+ gtk_check_menu_item_set_active(
+ GTK_CHECK_MENU_ITEM(*menuitem), init_value);
+ gtk_menu_shell_append (GTK_MENU_SHELL (*menu), *menuitem);
+ gtk_widget_show(*menuitem);
+ g_signal_connect(*menuitem, "toggled", func, NULL);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ if (g_getenv ("FERRET_ASCII"))
+ display_ascii = TRUE;
+
+ if (g_getenv ("FERRET_NOSIGNALS"))
+ no_signals = TRUE;
+
+ if (display_ascii)
+ g_print("GTK ferret Module loaded\n");
+
+ if (g_getenv("FERRET_MAGNIFIER"))
+ use_magnifier = TRUE;
+
+ if (g_getenv ("FERRET_FESTIVAL"))
+ use_festival = TRUE;
+
+ if (g_getenv ("FERRET_MOUSETRACK"))
+ track_mouse = TRUE;
+
+ if (g_getenv ("FERRET_TERSE"))
+ {
+ say_role = FALSE;
+ say_accel = FALSE;
+ }
+
+ _init_data();
+
+ _create_window();
+
+ _create_event_watcher();
+
+ return 0;
+}
+
+static void
+_clear_tab(TabNumber tab_n)
+{
+ GList *group_list, *nv_list;
+ TabInfo *tab;
+ GroupInfo *group;
+ NameValue *nv;
+
+ tab = nbook_tabs[tab_n];
+
+ for (group_list = tab->groups; group_list; group_list = group_list->next)
+ {
+ group = (GroupInfo *) group_list->data;
+
+ if (group->is_scrolled)
+ gtk_widget_hide(GTK_WIDGET(group->scroll_outer_frame));
+
+ gtk_widget_hide(GTK_WIDGET(group->frame));
+ gtk_widget_hide(GTK_WIDGET(group->group_vbox));
+
+ for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
+ {
+ nv = (NameValue *) nv_list->data;
+ nv->active = FALSE;
+ gtk_widget_hide(GTK_WIDGET(nv->column1));
+ gtk_widget_hide(GTK_WIDGET(nv->column2));
+ gtk_widget_hide(GTK_WIDGET(nv->label));
+
+ switch (nv->type)
+ {
+ case VALUE_STRING:
+ gtk_widget_hide(GTK_WIDGET(nv->string));
+ break;
+ case VALUE_BOOLEAN:
+ gtk_widget_hide(GTK_WIDGET(nv->boolean));
+ break;
+ case VALUE_TEXT:
+ gtk_widget_hide(GTK_WIDGET(nv->text));
+ break;
+ case VALUE_BUTTON:
+ gtk_widget_hide(GTK_WIDGET(nv->button));
+ break;
+ }
+ gtk_widget_hide(GTK_WIDGET(nv->hbox));
+
+ /* Disconnect signal handler if any */
+ if (nv->signal_id != -1)
+ g_signal_handler_disconnect(nv->button, nv->signal_id);
+
+ nv->signal_id = -1;
+ }
+ }
+}
+
+static gint
+_print_groupname(TabNumber tab_n, GroupId group_id,
+ const char *groupname)
+{
+ TabInfo *tab;
+ GroupInfo *the_group;
+ gint rc = -1;
+
+ if (display_ascii)
+ g_print("\n<%s>\n", groupname);
+
+ tab = nbook_tabs[tab_n];
+ the_group = _get_group(tab, group_id, groupname);
+ rc = g_list_index(tab->groups, the_group);
+ return rc;
+}
+
+static GroupInfo*
+_get_group(TabInfo *tab, GroupId group_id, const gchar *groupname)
+{
+ GroupInfo *group = NULL;
+ gboolean found = FALSE;
+ GList *group_list;
+
+ for (group_list = tab->groups; group_list; group_list = group_list->next)
+ {
+ group = (GroupInfo *) group_list->data;
+ if (group_id == group->group_id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ /* build a new one */
+ group = (GroupInfo *)g_new0(GroupInfo, 1);
+ group->group_id = group_id;
+ _get_group_scrolled(group);
+
+ if (group->is_scrolled)
+ {
+ group->frame = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_set_size_request (GTK_WIDGET (group->frame), -2,
+ group->default_height);
+ group->scroll_outer_frame = GTK_FRAME(gtk_frame_new(groupname));
+ gtk_container_add(GTK_CONTAINER(group->scroll_outer_frame),
+ group->frame);
+ }
+ else
+ {
+ group->frame = gtk_frame_new(groupname);
+ }
+
+ gtk_container_set_border_width(GTK_CONTAINER(group->frame), 10);
+
+ group->name = g_strdup(groupname);
+ group->group_vbox = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 10));
+
+ if (group->is_scrolled)
+ {
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (group->frame),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport(
+ GTK_SCROLLED_WINDOW(group->frame),
+ GTK_WIDGET(group->group_vbox));
+ }
+ else
+ {
+ gtk_container_add(GTK_CONTAINER(group->frame),
+ GTK_WIDGET(group->group_vbox));
+ }
+
+ tab->groups = g_list_append (tab->groups, group);
+
+ if (group->is_scrolled)
+ {
+ gtk_box_pack_start (GTK_BOX (tab->main_box),
+ GTK_WIDGET (group->scroll_outer_frame),
+ TRUE, TRUE, 0);
+ }
+ else
+ {
+ gtk_box_pack_start (GTK_BOX (tab->main_box),
+ GTK_WIDGET (group->frame),
+ TRUE, TRUE, 0);
+ }
+ }
+
+ return group;
+}
+
+void
+_get_group_scrolled(GroupInfo *group)
+{
+ if (group->group_id == OBJECT_INTERFACE)
+ {
+ group->is_scrolled = FALSE;
+ }
+ else if (group->group_id == RELATION_INTERFACE)
+ {
+ group->is_scrolled = TRUE;
+ group->default_height = 50;
+ }
+ else if (group->group_id == STATE_INTERFACE)
+ {
+ group->is_scrolled = TRUE;
+ group->default_height = 100;
+ }
+ else if (group->group_id == ACTION_INTERFACE)
+ {
+ group->is_scrolled = TRUE;
+ group->default_height = 200;
+ }
+ else if (group->group_id == TEXT_ATTRIBUTES)
+ {
+ group->is_scrolled = TRUE;
+ group->default_height = 70;
+ }
+ else
+ {
+ group->is_scrolled = FALSE;
+ }
+}
+
+NameValue *
+_get_name_value(GroupInfo *group, const gchar *label,
+ gpointer value_ptr, ValueType type)
+{
+ NameValue *name_value = NULL;
+ GList *nv_list;
+ GValue *value;
+ gboolean found = FALSE;
+ static char *empty_string = "";
+
+ if (!label)
+ {
+ label = empty_string;
+ }
+
+ for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
+ {
+ name_value = (NameValue *) nv_list->data;
+ if (!name_value->active)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ name_value = (NameValue *)g_new0(NameValue, 1);
+ name_value->column1 = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10));
+ name_value->column2 = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10));
+ name_value->hbox = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5));
+ name_value->label = GTK_LABEL(gtk_label_new(label));
+ name_value->string = gtk_label_new (NULL);
+ name_value->boolean = gtk_check_button_new ();
+ gtk_entry_buffer_set_max_length (gtk_entry_get_buffer (GTK_ENTRY (name_value->text)), 1000);
+ name_value->button = GTK_BUTTON(gtk_button_new ());
+
+ gtk_box_pack_end(GTK_BOX(name_value->column1),
+ GTK_WIDGET(name_value->label), FALSE, FALSE, 10);
+
+ switch (type)
+ {
+ case VALUE_STRING:
+ gtk_label_set_text(GTK_LABEL(name_value->string),
+ (gchar *) value_ptr);
+ gtk_box_pack_start(GTK_BOX(name_value->column2),
+ GTK_WIDGET(name_value->string), FALSE, FALSE, 10);
+ break;
+ case VALUE_BOOLEAN:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
+ *((gboolean *)value_ptr));
+ gtk_widget_set_sensitive(name_value->boolean, FALSE);
+ gtk_box_pack_start(GTK_BOX(name_value->column2),
+ GTK_WIDGET(name_value->boolean), FALSE, FALSE, 10);
+ break;
+ case VALUE_TEXT:
+ gtk_entry_set_text (GTK_ENTRY (name_value->text),
+ (gchar *)value_ptr);
+ gtk_box_pack_start(GTK_BOX(name_value->column2),
+ GTK_WIDGET(name_value->text), FALSE, FALSE, 10);
+ case VALUE_BUTTON:
+ value = &(name_value->button_gval);
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, (gchar *)value_ptr);
+ g_object_set_property(G_OBJECT(name_value->button),
+ "label", value);
+ gtk_box_pack_start(GTK_BOX(name_value->column2),
+ GTK_WIDGET(name_value->button), FALSE, FALSE, 10);
+ break;
+ }
+
+ gtk_box_pack_start (GTK_BOX (name_value->hbox),
+ GTK_WIDGET (name_value->column1),
+ TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (name_value->hbox),
+ GTK_WIDGET (name_value->column2),
+ TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(group->group_vbox),
+ GTK_WIDGET(name_value->hbox));
+ group->name_value = g_list_append (group->name_value, name_value);
+ }
+ else
+ {
+ gtk_label_set_text(GTK_LABEL(name_value->label), label);
+ switch (type)
+ {
+ case VALUE_STRING:
+ gtk_label_set_text(GTK_LABEL(name_value->string),
+ (gchar *) value_ptr);
+ break;
+ case VALUE_BOOLEAN:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
+ *((gboolean *)value_ptr));
+ gtk_widget_set_sensitive(name_value->boolean, FALSE);
+ break;
+ case VALUE_TEXT:
+ gtk_entry_set_text (GTK_ENTRY (name_value->text),
+ (gchar *) value_ptr);
+ break;
+ case VALUE_BUTTON:
+ value = &(name_value->button_gval);
+ memset (value, 0, sizeof (GValue));
+ g_value_init (value, G_TYPE_STRING);
+ g_value_set_string (value, (gchar *)value_ptr);
+ g_object_set_property(G_OBJECT(name_value->button),
+ "label", value);
+ break;
+ }
+ }
+
+ name_value->active = TRUE;
+ name_value->type = type;
+ name_value->signal_id = -1;
+
+ gtk_widget_show(GTK_WIDGET(name_value->label));
+
+ switch (type)
+ {
+ case VALUE_STRING:
+ gtk_widget_show(GTK_WIDGET(name_value->string));
+ break;
+ case VALUE_BOOLEAN:
+ gtk_widget_show(GTK_WIDGET(name_value->boolean));
+ break;
+ case VALUE_TEXT:
+ gtk_widget_show(GTK_WIDGET(name_value->text));
+ break;
+ case VALUE_BUTTON:
+ gtk_widget_show(GTK_WIDGET(name_value->button));
+ break;
+ }
+
+ gtk_widget_show(GTK_WIDGET(name_value->column1));
+ gtk_widget_show(GTK_WIDGET(name_value->column2));
+ gtk_widget_show(GTK_WIDGET(name_value->hbox));
+ gtk_widget_show(GTK_WIDGET(group->group_vbox));
+
+ return name_value;
+}
+
+static NameValue *
+_print_key_value(TabNumber tab_n, gint group_number,
+ const char *label, gpointer value, ValueType type)
+{
+ TabInfo *tab;
+ GroupInfo *the_group;
+
+ if (display_ascii)
+ {
+ if (type == VALUE_BOOLEAN)
+ {
+ if (*((gboolean *)value))
+ g_print("\t%-30s\tTRUE\n", label);
+ else
+ g_print("\t%-30s\tFALSE\n", label);
+ }
+ else
+ {
+ g_print("\t%-30s\t%s\n", label,
+ value ? (gchar *)value : "NULL");
+ }
+ }
+
+ tab = nbook_tabs[tab_n];
+ the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
+ return _get_name_value(the_group, label, (gpointer)value, type);
+}
+
+static void
+_finished_group(TabNumber tab_no, gint group_number)
+{
+ TabInfo *tab;
+ GroupInfo *the_group;
+
+ tab = nbook_tabs[tab_no];
+
+ the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
+
+ if (the_group->is_scrolled)
+ gtk_widget_show(GTK_WIDGET(the_group->scroll_outer_frame));
+
+ gtk_widget_show(GTK_WIDGET(the_group->frame));
+ gtk_widget_show(GTK_WIDGET(the_group->group_vbox));
+ gtk_widget_show(GTK_WIDGET(tab->main_box));
+}
+
+/* Signal handlers */
+
+static gulong child_added_id = 0;
+static gulong child_removed_id = 0;
+static gulong state_change_id = 0;
+
+static gulong text_caret_handler_id = 0;
+static gulong text_inserted_id = 0;
+static gulong text_deleted_id = 0;
+
+static gulong table_row_inserted_id = 0;
+static gulong table_column_inserted_id = 0;
+static gulong table_row_deleted_id = 0;
+static gulong table_column_deleted_id = 0;
+static gulong table_row_reordered_id = 0;
+static gulong table_column_reordered_id = 0;
+
+static gulong property_id = 0;
+
+static void
+_update_handlers(AtkObject *obj)
+{
+ /* Remove signal handlers from object that had focus before */
+
+ if (last_object != NULL && G_TYPE_CHECK_INSTANCE(last_object))
+ {
+ if (child_added_id != 0)
+ g_signal_handler_disconnect(last_object, child_added_id);
+ if (child_removed_id != 0)
+ g_signal_handler_disconnect(last_object, child_removed_id);
+ if (state_change_id != 0)
+ g_signal_handler_disconnect(last_object, state_change_id);
+
+ if (text_caret_handler_id != 0)
+ g_signal_handler_disconnect(last_object, text_caret_handler_id);
+ if (text_inserted_id != 0)
+ g_signal_handler_disconnect(last_object, text_inserted_id);
+ if (text_deleted_id != 0)
+ g_signal_handler_disconnect(last_object, text_deleted_id);
+
+ if (table_row_inserted_id != 0)
+ g_signal_handler_disconnect(last_object, table_row_inserted_id);
+ if (table_column_inserted_id != 0)
+ g_signal_handler_disconnect(last_object, table_column_inserted_id);
+ if (table_row_deleted_id != 0)
+ g_signal_handler_disconnect(last_object, table_row_deleted_id);
+ if (table_column_deleted_id != 0)
+ g_signal_handler_disconnect(last_object, table_column_deleted_id);
+ if (table_row_reordered_id != 0)
+ g_signal_handler_disconnect(last_object, table_row_reordered_id);
+ if (table_column_reordered_id != 0)
+ g_signal_handler_disconnect(last_object, table_column_reordered_id);
+ if (property_id != 0)
+ g_signal_handler_disconnect(last_object, property_id);
+
+ g_object_unref(last_object);
+ }
+
+ last_object = NULL;
+
+ child_added_id = 0;
+ child_removed_id = 0;
+ text_caret_handler_id = 0;
+ text_inserted_id = 0;
+ text_deleted_id = 0;
+ table_row_inserted_id = 0;
+ table_column_inserted_id = 0;
+ table_row_deleted_id = 0;
+ table_column_deleted_id = 0;
+ table_row_reordered_id = 0;
+ table_column_reordered_id = 0;
+ property_id = 0;
+
+ if (!G_TYPE_CHECK_INSTANCE(obj))
+ return;
+
+ g_object_ref(obj);
+ last_object = obj;
+
+ /* Add signal handlers to object that now has focus. */
+
+ if (ATK_IS_OBJECT(obj))
+ {
+ child_added_id = g_signal_connect_closure (obj,
+ "children_changed::add",
+ g_cclosure_new (G_CALLBACK (_notify_object_child_added),
+ NULL, NULL), FALSE);
+
+ child_removed_id = g_signal_connect_closure (obj,
+ "children_changed::remove",
+ g_cclosure_new (G_CALLBACK (_notify_object_child_removed),
+ NULL, NULL), FALSE);
+
+ state_change_id = g_signal_connect_closure (obj,
+ "state_change",
+ g_cclosure_new (G_CALLBACK (_notify_object_state_change),
+ NULL, NULL), FALSE);
+ }
+
+ if (ATK_IS_TEXT(obj))
+ {
+ text_caret_handler_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("text_caret_moved", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_caret_handler),
+ NULL, NULL), FALSE);
+ text_inserted_id = g_signal_connect_closure (obj,
+ "text_changed::insert",
+ g_cclosure_new (G_CALLBACK (_notify_text_insert_handler),
+ NULL, NULL), FALSE);
+ text_deleted_id = g_signal_connect_closure (obj,
+ "text_changed::delete",
+ g_cclosure_new (G_CALLBACK (_notify_text_delete_handler),
+ NULL, NULL), FALSE);
+ }
+
+ if (ATK_IS_TABLE(obj))
+ {
+ table_row_inserted_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_inserted", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_row_inserted),
+ NULL, NULL), FALSE);
+ table_column_inserted_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_inserted", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_column_inserted),
+ NULL, NULL), FALSE);
+ table_row_deleted_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_deleted", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_row_deleted),
+ NULL, NULL), FALSE);
+ table_column_deleted_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_deleted", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_column_deleted),
+ NULL, NULL), FALSE);
+ table_row_reordered_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_reordered", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_row_reordered),
+ NULL, NULL), FALSE);
+ table_column_reordered_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_reordered", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_notify_table_column_reordered),
+ NULL, NULL), FALSE);
+ }
+
+ property_id = g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("property_change", G_OBJECT_TYPE (obj)),
+ 0, g_cclosure_new (G_CALLBACK (_property_change_handler),
+ NULL, NULL),
+ FALSE);
+}
+
+/* Text signals */
+
+static void
+_notify_text_insert_handler (GObject *obj, int position, int offset)
+{
+ gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
+ gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
+ position, offset, text ? text: "<NULL>");
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
+ "Text Insert", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_text_delete_handler (GObject *obj, int position, int offset)
+{
+ gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
+ gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
+ position, offset, text ? text: "<NULL>");
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
+ "Text Delete", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_caret_handler (GObject *obj, int position)
+{
+ gchar *output_str = g_strdup_printf("position %d", position);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
+ "Text Caret Moved", output_str);
+ g_free(output_str);
+}
+
+/* Table signals */
+
+static void
+_notify_table_row_inserted (GObject *obj, gint start_offset,
+ gint length)
+{
+ gchar *output_str =
+ g_strdup_printf("position %d, num of rows inserted %d!\n",
+ start_offset, length);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Row Inserted", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_table_column_inserted (GObject *obj, gint start_offset,
+ gint length)
+{
+ gchar *output_str =
+ g_strdup_printf("position %d, num of rows inserted %d!\n",
+ start_offset, length);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Column Inserted", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_table_row_deleted (GObject *obj, gint start_offset,
+ gint length)
+{
+ gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
+ start_offset, length);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Row Deleted", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_table_column_deleted (GObject *obj, gint start_offset,
+ gint length)
+{
+ gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
+ start_offset, length);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Column Deleted", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_table_row_reordered (GObject *obj)
+{
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Row Reordered", NULL);
+}
+
+static void
+_notify_table_column_reordered (GObject *obj)
+{
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
+ "Table Column Reordered", NULL);
+}
+
+/* Object signals */
+
+static void
+_notify_object_child_added (GObject *obj, gint index,
+ AtkObject *child)
+{
+ gchar *output_str = g_strdup_printf("index %d", index);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
+ "Child Added", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_object_child_removed (GObject *obj, gint index,
+ AtkObject *child)
+{
+ gchar *output_str = g_strdup_printf("index %d", index);
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
+ "Child Removed", output_str);
+ g_free(output_str);
+}
+
+static void
+_notify_object_state_change (GObject *obj, gchar *name, gboolean set)
+{
+ gchar *output_str = g_strdup_printf("name %s %s set",
+ name, set ? "is" : "was");
+ _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
+ "State Change", output_str);
+ g_free(output_str);
+}
+
+
+/* Function to print signals */
+
+static void
+_print_signal(AtkObject *aobject, FerretSignalType type,
+ const char *name, const char *info)
+{
+ TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
+
+ if (no_signals)
+ return;
+
+ if (display_ascii)
+ {
+ if (info != NULL)
+ g_print("SIGNAL:\t%-34s\t%s\n", name, info);
+ else
+ g_print("SIGNAL:\t%-34s\n", name);
+ }
+
+ if (use_festival)
+ {
+ if ((type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
+ {
+ _speak_caret_event (aobject);
+ }
+ else if (type == FERRET_SIGNAL_TEXT)
+ {
+ last_caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
+ }
+ }
+
+ if (use_magnifier && ATK_IS_TEXT (aobject) &&
+ (type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
+ {
+ gint x, y, w, h;
+ gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
+ atk_text_get_character_extents ( ATK_TEXT (aobject), caret_offset, &x, &y, &w, &h, ATK_XY_SCREEN);
+ _send_to_magnifier (x, y, w, h);
+ }
+
+ if ((type == FERRET_SIGNAL_TEXT && top_tab == TEXT) ||
+ (type == FERRET_SIGNAL_TABLE && top_tab == TABLE) ||
+ (type == FERRET_SIGNAL_OBJECT && top_tab == OBJECT))
+ {
+ if (display_ascii)
+ g_print("Updating tab\n");
+
+ _update(top_tab, aobject);
+ }
+}
+
+/* Update functions */
+
+static void
+_update (TabNumber top_tab, AtkObject *aobject)
+{
+ gint group_num;
+
+ if (top_tab >= OBJECT && top_tab < END_TABS)
+ {
+ _clear_tab(top_tab);
+ }
+
+ if (top_tab == OBJECT && ATK_IS_OBJECT(aobject))
+ {
+ group_num = _print_object(aobject);
+ _finished_group(OBJECT, group_num);
+ group_num = _print_relation(aobject);
+ _finished_group(OBJECT, group_num);
+ group_num = _print_state(aobject);
+ _finished_group(OBJECT, group_num);
+ }
+ if (top_tab == TEXT && ATK_IS_TEXT(aobject))
+ {
+ group_num = _print_text(ATK_TEXT (aobject));
+ _finished_group(TEXT, group_num);
+ group_num = _print_text_attributes(ATK_TEXT (aobject));
+ _finished_group(TEXT, group_num);
+ }
+ if (top_tab == SELECTION && ATK_IS_SELECTION(aobject))
+ {
+ group_num = _print_selection(ATK_SELECTION (aobject));
+ _finished_group(SELECTION, group_num);
+ }
+ if (top_tab == TABLE && ATK_IS_TABLE(aobject))
+ {
+ group_num = _print_table(ATK_TABLE (aobject));
+ _finished_group(TABLE, group_num);
+ }
+ if (top_tab == ACTION && ATK_IS_ACTION(aobject))
+ {
+ group_num = _print_action(ATK_ACTION (aobject));
+ _finished_group(ACTION, group_num);
+ }
+ if (top_tab == COMPONENT && ATK_IS_COMPONENT(aobject))
+ {
+ group_num = _print_component(ATK_COMPONENT(aobject));
+ _finished_group(COMPONENT, group_num);
+ }
+ if (top_tab == IMAGE && ATK_IS_IMAGE(aobject))
+ {
+ group_num = _print_image(ATK_IMAGE (aobject));
+ _finished_group(IMAGE, group_num);
+ }
+ if (top_tab == VALUE && ATK_IS_VALUE(aobject))
+ {
+ group_num = _print_value(ATK_VALUE(aobject));
+ _finished_group(VALUE, group_num);
+ }
+}
+
+static void
+_update_current_page(GtkNotebook *notebook, gpointer p, guint current_page)
+{
+ _update(current_page+OBJECT, last_object);
+}
+
+/* Property listeners */
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
+
+ if (no_signals)
+ return;
+
+ /*
+ * Only process if the property change corrisponds to the current
+ * object
+ */
+ if (obj != last_object)
+ {
+ if (display_ascii)
+ {
+ g_print("\nProperty change event <%s> for object not in focus\n",
+ values->property_name);
+ }
+
+ return;
+ }
+
+ if (display_ascii)
+ {
+ g_print("\nProperty change event <%s> occurred.\n",
+ values->property_name);
+ }
+
+ /*
+ * Update the top tab if a property changes.
+ *
+ * We may be able to ignore some property changes if they do not
+ * change anything in ferret.
+ */
+
+ if (top_tab == OBJECT &&
+ ((strcmp (values->property_name, "accessible-name") == 0) ||
+ (strcmp (values->property_name, "accessible-description") == 0) ||
+ (strcmp (values->property_name, "accessible-parent") == 0) ||
+ (strcmp (values->property_name, "accessible-value") == 0) ||
+ (strcmp (values->property_name, "accessible-role") == 0) ||
+ (strcmp (values->property_name, "accessible-component-layout") == 0) ||
+ (strcmp (values->property_name, "accessible-component-mdi-zorder") == 0) ||
+ (strcmp (values->property_name, "accessible-table-caption") == 0) ||
+ (strcmp (values->property_name,
+ "accessible-table-column-description") == 0) ||
+ (strcmp (values->property_name,
+ "accessible-table-column-header") == 0) ||
+ (strcmp (values->property_name,
+ "accessible-table-row-description") == 0) ||
+ (strcmp (values->property_name,
+ "accessible-table-row-header") == 0) ||
+ (strcmp (values->property_name, "accessible-table-summary") == 0)))
+ {
+ if (display_ascii)
+ g_print("Updating tab\n");
+
+ _update(top_tab, last_object);
+ }
+ else if (top_tab == VALUE &&
+ (strcmp (values->property_name, "accessible-value") == 0))
+ {
+ if (display_ascii)
+ g_print("Updating tab\n");
+
+ _update(top_tab, last_object);
+ }
+}
+
+/* Action button callback function */
+
+void _action_cb(GtkWidget *widget, gpointer *userdata)
+{
+ NameValue *nv = (NameValue *)userdata;
+ atk_action_do_action(ATK_ACTION(nv->atkobj), nv->action_num);
+}
+
+/* Menu-bar callback functions */
+
+void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (gtk_check_menu_item_get_active (checkmenuitem))
+ display_ascii = TRUE;
+ else
+ display_ascii = FALSE;
+}
+
+void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (gtk_check_menu_item_get_active (checkmenuitem))
+ no_signals = TRUE;
+ else
+ no_signals = FALSE;
+}
+
+void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (gtk_check_menu_item_get_active (checkmenuitem))
+ use_magnifier = TRUE;
+ else
+ use_magnifier = FALSE;
+}
+
+void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (gtk_check_menu_item_get_active (checkmenuitem))
+ use_festival = TRUE;
+ else
+ use_festival = FALSE;
+}
+
+void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (gtk_check_menu_item_get_active (checkmenuitem))
+ {
+ say_role = FALSE;
+ say_accel = FALSE;
+ }
+ else
+ {
+ say_role = TRUE;
+ say_accel = TRUE;
+ }
+}
+
+void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (gtk_check_menu_item_get_active (checkmenuitem))
+ {
+ mouse_watcher_focus_id =
+ atk_add_global_event_listener(_mouse_watcher,
+ "Gtk:GtkWidget:enter_notify_event");
+ mouse_watcher_button_id =
+ atk_add_global_event_listener(_button_watcher,
+ "Gtk:GtkWidget:button_press_event");
+ track_mouse = TRUE;
+ }
+ else
+ {
+ if (mouse_watcher_focus_id != -1)
+ {
+ atk_remove_global_event_listener(mouse_watcher_focus_id);
+ atk_remove_global_event_listener(mouse_watcher_button_id);
+ track_mouse = FALSE;
+ }
+ }
+}
+
+void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
+ gpointer user_data)
+{
+ if (gtk_check_menu_item_get_active (checkmenuitem))
+ {
+ track_focus = TRUE;
+ focus_tracker_id = atk_add_focus_tracker (_print_accessible);
+ }
+ else
+ {
+ g_print ("No longer tracking focus.\n");
+ track_focus = FALSE;
+ atk_remove_focus_tracker (focus_tracker_id);
+ }
+}
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+/*
+ * This module is used to test the implementation of AtkAction,
+ * i.e. the getting of the name and the getting and setting of description
+ */
+
+static void _create_event_watcher (void);
+static void _check_object (AtkObject *obj);
+
+static void
+_check_object (AtkObject *obj)
+{
+ const char *accessible_name;
+ const gchar * typename = NULL;
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget* widget = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ typename = g_type_name (G_OBJECT_TYPE (widget));
+ g_print ("Widget type name: %s\n", typename ? typename : "NULL");
+ }
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("Accessible type name: %s\n", typename ? typename : "NULL");
+ accessible_name = atk_object_get_name (obj);
+ if (accessible_name)
+ g_print ("Name: %s\n", accessible_name);
+
+ if (ATK_IS_ACTION (obj))
+ {
+ AtkAction *action = ATK_ACTION (obj);
+ gint n_actions, i;
+ const gchar *action_name;
+ const gchar *action_desc;
+ const gchar *action_binding;
+ const gchar *desc = "Test description";
+
+ n_actions = atk_action_get_n_actions (action);
+ g_print ("AtkAction supported number of actions: %d\n", n_actions);
+ for (i = 0; i < n_actions; i++)
+ {
+ action_name = atk_action_get_name (action, i);
+ g_print ("Name of Action %d: %s\n", i, action_name);
+ action_binding = atk_action_get_keybinding (action, i);
+ if (action_binding)
+ g_print ("Name of Action Keybinding %d: %s\n", i, action_binding);
+
+ if (!atk_action_set_description (action, i, desc))
+ {
+ g_print ("atk_action_set_description failed\n");
+ }
+ else
+ {
+ action_desc = atk_action_get_description (action, i);
+ if (strcmp (desc, action_desc) != 0)
+ {
+ g_print ("Problem with setting and getting action description\n");
+ }
+ }
+ }
+ if (atk_action_set_description (action, n_actions, desc))
+ {
+ g_print ("atk_action_set_description succeeded but should not have\n");
+ }
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_object);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testaction Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+/*
+ * This module is used to test the accessible implementation for buttons
+ *
+ * 1) It verifies that ATK_STATE_ARMED is set when a button is pressed
+ * To check this click on the button whose name is specified in the
+ * environment variable TEST_ACCESSIBLE_NAME or "button box" if the
+ * environment variable is not set.
+ *
+ * 2) If the environment variable TEST_ACCESSIBLE_AUTO is set the program
+ * will execute the action defined for a GailButton once.
+ *
+ * 3) Change an inconsistent toggle button to be consistent and vice versa.
+ *
+ * Note that currently this code needs to be changed manually to test
+ * different actions.
+ */
+
+static void _create_event_watcher (void);
+static void _check_object (AtkObject *obj);
+static void button_pressed_handler (GtkButton *button);
+static void _print_states (AtkObject *obj);
+static void _print_button_image_info(AtkObject *obj);
+static gint _do_button_action (gpointer data);
+static gint _toggle_inconsistent (gpointer data);
+static gint _finish_button_action (gpointer data);
+
+#define NUM_VALID_ROLES 4
+
+static void
+_check_object (AtkObject *obj)
+{
+ AtkRole role;
+ static gboolean first_time = TRUE;
+
+ role = atk_object_get_role (obj);
+ if (role == ATK_ROLE_FRAME)
+ /*
+ * Find the specified button in the window
+ */
+ {
+ AtkRole valid_roles[NUM_VALID_ROLES];
+ const char *name;
+ AtkObject *atk_button;
+ GtkWidget *widget;
+
+ valid_roles[0] = ATK_ROLE_PUSH_BUTTON;
+ valid_roles[1] = ATK_ROLE_TOGGLE_BUTTON;
+ valid_roles[2] = ATK_ROLE_CHECK_BOX;
+ valid_roles[3] = ATK_ROLE_RADIO_BUTTON;
+
+ name = g_getenv ("TEST_ACCESSIBLE_NAME");
+ if (name == NULL)
+ name = "button box";
+ atk_button = find_object_by_accessible_name_and_role (obj, name,
+ valid_roles, NUM_VALID_ROLES);
+
+ if (atk_button == NULL)
+ {
+ g_print ("Object not found for %s\n", name);
+ return;
+ }
+ g_assert (GTK_IS_ACCESSIBLE (atk_button));
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_button));
+ g_assert (GTK_IS_BUTTON (widget));
+ g_signal_connect (widget,
+ "pressed",
+ G_CALLBACK (button_pressed_handler),
+ NULL);
+ if (GTK_IS_TOGGLE_BUTTON (widget))
+ {
+ _toggle_inconsistent (GTK_TOGGLE_BUTTON (widget));
+ }
+ if (first_time)
+ first_time = FALSE;
+ else
+ return;
+
+ if (g_getenv ("TEST_ACCESSIBLE_AUTO"))
+ {
+ g_idle_add (_do_button_action, atk_button);
+ }
+ }
+}
+
+static gint _toggle_inconsistent (gpointer data)
+{
+ GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (data);
+
+ if (gtk_toggle_button_get_inconsistent (toggle_button))
+ {
+ gtk_toggle_button_set_inconsistent (toggle_button, FALSE);
+ }
+ else
+ {
+ gtk_toggle_button_set_inconsistent (toggle_button, TRUE);
+ }
+ return FALSE;
+}
+
+static gint _do_button_action (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+
+ atk_action_do_action (ATK_ACTION (obj), 2);
+
+ g_timeout_add (5000, _finish_button_action, obj);
+ return FALSE;
+}
+
+static gint _finish_button_action (gpointer data)
+{
+#if 0
+ AtkObject *obj = ATK_OBJECT (data);
+
+ atk_action_do_action (ATK_ACTION (obj), 0);
+#endif
+
+ return FALSE;
+}
+
+static void
+button_pressed_handler (GtkButton *button)
+{
+ AtkObject *obj;
+
+ obj = gtk_widget_get_accessible (GTK_WIDGET (button));
+ _print_states (obj);
+ _print_button_image_info (obj);
+
+ if (GTK_IS_TOGGLE_BUTTON (button))
+ {
+ g_idle_add (_toggle_inconsistent, GTK_TOGGLE_BUTTON (button));
+ }
+}
+
+static void
+_print_states (AtkObject *obj)
+{
+ AtkStateSet *state_set;
+ gint i;
+
+ state_set = atk_object_ref_state_set (obj);
+
+ g_print ("*** Start states ***\n");
+ for (i = 0; i < 64; i++)
+ {
+ AtkStateType one_state;
+ const gchar *name;
+
+ if (atk_state_set_contains_state (state_set, i))
+ {
+ one_state = i;
+
+ name = atk_state_type_get_name (one_state);
+
+ if (name)
+ g_print("%s\n", name);
+ }
+ }
+ g_object_unref (state_set);
+ g_print ("*** End states ***\n");
+}
+
+static void
+_print_button_image_info(AtkObject *obj) {
+
+ gint height, width;
+ const gchar *desc;
+
+ height = width = 0;
+
+ if(!ATK_IS_IMAGE(obj))
+ return;
+
+ g_print("*** Start Button Image Info ***\n");
+ desc = atk_image_get_image_description(ATK_IMAGE(obj));
+ g_print ("atk_image_get_image_desc returns : %s\n", desc ? desc : "<NULL>");
+ atk_image_get_image_size(ATK_IMAGE(obj), &height ,&width);
+ g_print("atk_image_get_image_size returns: height %d width %d\n",height,width);
+ if(atk_image_set_image_description(ATK_IMAGE(obj), "New image Description")){
+ desc = atk_image_get_image_description(ATK_IMAGE(obj));
+ g_print ("atk_image_get_image_desc now returns : %s\n",desc ?desc:"<NULL>");
+ }
+ g_print("*** End Button Image Info ***\n");
+
+
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_object);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testbutton Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+static void _test_selection (AtkObject *obj);
+static void _check_combo_box (AtkObject *obj);
+static void _check_children (AtkObject *obj);
+static gint _open_combo_list (gpointer data);
+static gint _close_combo_list (gpointer data);
+
+#define NUM_VALID_ROLES 1
+
+static void _check_children (AtkObject *obj)
+{
+ gint n_children, i, j;
+ AtkObject *child;
+ AtkObject *grand_child;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+
+ if (n_children > 1)
+ {
+ g_print ("*** Unexpected number of children for combo box: %d\n",
+ n_children);
+ return;
+ }
+ if (n_children == 2)
+ {
+ child = atk_object_ref_accessible_child (obj, 1);
+ g_return_if_fail (atk_object_get_role (child) == ATK_ROLE_TEXT);
+ j = atk_object_get_index_in_parent (child);
+ if (j != 1)
+ g_print ("*** inconsistency between parent and children %d %d ***\n",
+ 1, j);
+ g_object_unref (G_OBJECT (child));
+ }
+
+ child = atk_object_ref_accessible_child (obj, 0);
+ g_return_if_fail (atk_object_get_role (child) == ATK_ROLE_LIST);
+ j = atk_object_get_index_in_parent (child);
+ if (j != 0)
+ g_print ("*** inconsistency between parent and children %d %d ***\n",
+ 0, j);
+
+ n_children = atk_object_get_n_accessible_children (child);
+ for (i = 0; i < n_children; i++)
+ {
+ const gchar *name;
+
+ grand_child = atk_object_ref_accessible_child (child, i);
+ name = atk_object_get_name (grand_child);
+ g_print ("Index: %d Name: %s\n", i, name ? name : "<NULL>");
+ g_object_unref (G_OBJECT (grand_child));
+ }
+ g_object_unref (G_OBJECT (child));
+}
+
+static void _test_selection (AtkObject *obj)
+{
+ gint count;
+ gint n_children;
+ AtkObject *list;
+
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_if_fail (count == 0);
+
+ list = atk_object_ref_accessible_child (obj, 0);
+ n_children = atk_object_get_n_accessible_children (list);
+ g_object_unref (G_OBJECT (list));
+
+ atk_selection_add_selection (ATK_SELECTION (obj), n_children - 1);
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_if_fail (count == 1);
+ g_return_if_fail (atk_selection_is_child_selected (ATK_SELECTION (obj),
+ n_children - 1));
+ atk_selection_add_selection (ATK_SELECTION (obj), 0);
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_if_fail (count == 1);
+ g_return_if_fail (atk_selection_is_child_selected (ATK_SELECTION (obj), 0));
+ atk_selection_clear_selection (ATK_SELECTION (obj));
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_if_fail (count == 0);
+}
+
+static void _check_combo_box (AtkObject *obj)
+{
+ static gboolean done = FALSE;
+ static gboolean done_selection = FALSE;
+ AtkRole role;
+
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME)
+ {
+ AtkRole roles[NUM_VALID_ROLES];
+ AtkObject *combo_obj;
+
+ if (done_selection)
+ return;
+
+ roles[0] = ATK_ROLE_COMBO_BOX;
+
+ combo_obj = find_object_by_role (obj, roles, NUM_VALID_ROLES);
+
+ if (combo_obj)
+ {
+ if (!done_selection)
+ {
+ done_selection = TRUE;
+ }
+ if (g_getenv ("TEST_ACCESSIBLE_COMBO_NOEDIT") != NULL)
+ {
+ GtkWidget *combo;
+ GtkEntry *entry;
+
+ combo = gtk_accessible_get_widget (GTK_ACCESSIBLE (combo_obj));
+ entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo)));
+ gtk_editable_set_editable (GTK_EDITABLE (entry), FALSE);
+ }
+ _check_children (combo_obj);
+ _test_selection (combo_obj);
+ }
+
+ return;
+ }
+ if (role != ATK_ROLE_COMBO_BOX)
+ return;
+
+ g_print ("*** Start ComboBox ***\n");
+ _check_children (obj);
+
+ if (!done)
+ {
+ g_idle_add ((GSourceFunc)_open_combo_list, obj);
+ done = TRUE;
+ }
+ else
+ return;
+ g_print ("*** End ComboBox ***\n");
+}
+
+static gint _open_combo_list (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+
+ g_print ("_open_combo_list\n");
+ atk_action_do_action (ATK_ACTION (obj), 0);
+
+ g_timeout_add (5000, _close_combo_list, obj);
+ return FALSE;
+}
+
+static gint _close_combo_list (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+
+ gint count;
+ gint n_children;
+ AtkObject *list;
+
+ count = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_val_if_fail (count == 0, FALSE);
+
+ list = atk_object_ref_accessible_child (obj, 0);
+ n_children = atk_object_get_n_accessible_children (list);
+ g_object_unref (G_OBJECT (list));
+
+ atk_selection_add_selection (ATK_SELECTION (obj), n_children - 1);
+
+ atk_action_do_action (ATK_ACTION (obj), 0);
+
+ return FALSE;
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_combo_box);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testcombo Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <atk/atk.h>
+
+static void _check_position (AtkObject *obj);
+
+static void _check_position (AtkObject *obj)
+{
+ AtkObject *parent, *ret_object;
+
+ gint x, y, width, height;
+ gint x1, y1, width1, height1;
+
+ x = y = width = height = 0;
+ x1 = y1 = width1 = height1 = 0;
+
+ if (!ATK_IS_COMPONENT (obj))
+ return;
+
+ atk_component_get_extents (ATK_COMPONENT(obj), &x, &y, &width, &height, ATK_XY_SCREEN);
+ atk_component_get_position (ATK_COMPONENT(obj), &x1, &y1, ATK_XY_SCREEN );
+ atk_component_get_size (ATK_COMPONENT(obj), &width1, &height1);
+ if ((x1 != x) || (y1 != y))
+ {
+ g_print ("atk_component_get_extents and atk_get_position give different"
+ " values: %d,%d %d,%d\n", x, y, x1, y1);
+ }
+ if ((width1 != width) || (height1 != height))
+ {
+ g_print ("atk_component_get_extents and atk_get_size give different"
+ " values: %d,%d %d,%d\n", width, height, width1, height1);
+ }
+
+ atk_component_get_position (ATK_COMPONENT(obj), &x1, &y1, ATK_XY_SCREEN);
+ g_print ("Object Type: %s\n", g_type_name (G_OBJECT_TYPE (obj)));
+ g_print ("Object at %d, %d on screen\n", x1, y1);
+ g_print ("Object at %d, %d, size: %d, %d\n", x, y, width, height);
+
+ parent = atk_object_get_parent (obj);
+
+ if (ATK_IS_COMPONENT (parent))
+ {
+ gint px, py, pwidth, pheight;
+
+ atk_component_get_extents (ATK_COMPONENT(parent),
+ &px, &py, &pwidth, &pheight, ATK_XY_SCREEN);
+ g_print ("Parent Type: %s\n", g_type_name (G_OBJECT_TYPE (parent)));
+ g_print ("Parent at %d, %d, size: %d, %d\n", px, py, pwidth, pheight);
+ ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x, y, ATK_XY_SCREEN);
+
+ if (!ret_object)
+ {
+ g_print ("1:atk_component_ref_accessible_at_point returns NULL\n");
+ }
+ else if (ret_object != obj)
+ {
+ g_print ("1:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
+ x, y);
+ atk_component_get_extents (ATK_COMPONENT(ret_object),
+ &px, &py, &pwidth, &pheight, ATK_XY_SCREEN);
+ g_print ("ret_object at %d, %d, size: %d, %d\n", px, py, pwidth, pheight);
+ }
+ if (ret_object)
+ g_object_unref (G_OBJECT (ret_object));
+ ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x+width-1, y+height-1, ATK_XY_SCREEN);
+ if (!ret_object)
+ {
+ g_print ("2:atk_component_ref_accessible_at_point returns NULL\n");
+ }
+ else if (ret_object != obj)
+ {
+ g_print ("2:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
+ x+width-1, y+height-1);
+ }
+ if (ret_object)
+ g_object_unref (G_OBJECT (ret_object));
+ ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x-1, y-1, ATK_XY_SCREEN);
+ if ((ret_object) && (ret_object == obj))
+ {
+ g_print ("3:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
+ x-1, y-1);
+ }
+ if (ret_object)
+ g_object_unref (G_OBJECT (ret_object));
+ ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x+width, y+height, ATK_XY_SCREEN);
+ if ((ret_object) && (ret_object == obj))
+ {
+ g_print ("4:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
+ x+width, y+height);
+ }
+ if (ret_object)
+ g_object_unref (G_OBJECT (ret_object));
+ }
+ if (!atk_component_contains (ATK_COMPONENT(obj), x, y, ATK_XY_SCREEN))
+ g_print ("Component does not contain position, %d %d\n", x, y);
+ if (atk_component_contains (ATK_COMPONENT(obj), x-1, y-1, ATK_XY_SCREEN))
+ g_print ("Component does contain position, %d %d\n", x-1, y-1);
+ if (!atk_component_contains (ATK_COMPONENT(obj), x+width-1, y+height-1, ATK_XY_SCREEN))
+ g_print ("Component does not contain position, %d %d\n",
+ x+width-1, y+height-1);
+ if (atk_component_contains (ATK_COMPONENT(obj), x+width, y+height, ATK_XY_SCREEN))
+ g_print ("Component does contain position, %d %d\n", x+width, y+height);
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_position);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testcomponent Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <gtk/gtk.h>
+#include "testlib.h"
+#include <stdlib.h>
+
+/*
+ * This test modules tests the AtkImage interface. When the module is loaded
+ * with testgtk , it also creates a dialog that contains GtkArrows and a
+ * GtkImage.
+ *
+ */
+
+typedef struct
+{
+ GtkWidget *dialog;
+ GtkWidget *arrow1;
+ GtkWidget *arrow2;
+ GtkWidget *arrow3;
+ GtkWidget *arrow4;
+ GtkWidget *close_button;
+ GtkImage *image;
+}MainDialog;
+
+static void destroy (GtkWidget *widget, gpointer data)
+{
+ gtk_widget_destroy(GTK_WIDGET(data));
+}
+
+static void _check_arrows (AtkObject *obj)
+{
+ GtkWidget *content_area, *action_area;
+ AtkRole role;
+ MainDialog *md;
+ static gint visibleDialog = 0;
+
+
+ role = atk_object_get_role(obj);
+ if(role == ATK_ROLE_FRAME) {
+
+ md = (MainDialog *) malloc (sizeof(MainDialog));
+ if (visibleDialog == 0)
+ {
+ md->arrow1 = gtk_arrow_new(GTK_ARROW_UP,GTK_SHADOW_IN);
+ md->arrow2 = gtk_arrow_new(GTK_ARROW_DOWN,GTK_SHADOW_IN);
+ md->arrow3 = gtk_arrow_new(GTK_ARROW_LEFT,GTK_SHADOW_OUT);
+ md->arrow4 = gtk_arrow_new(GTK_ARROW_RIGHT,GTK_SHADOW_OUT);
+ md->dialog = gtk_dialog_new();
+ gtk_window_set_modal(GTK_WINDOW(md->dialog), TRUE);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (md->dialog));
+ action_area = gtk_dialog_get_action_area (GTK_DIALOG (md->dialog));
+
+ gtk_box_pack_start(GTK_BOX (content_area), md->arrow1, TRUE,TRUE, 0);
+ gtk_box_pack_start(GTK_BOX (content_area), md->arrow2, TRUE,TRUE, 0);
+ gtk_box_pack_start(GTK_BOX (content_area), md->arrow3, TRUE,TRUE, 0);
+ gtk_box_pack_start(GTK_BOX (content_area), md->arrow4, TRUE,TRUE, 0);
+ g_signal_connect(md->dialog, "destroy",
+ G_CALLBACK (destroy), md->dialog);
+
+ md->image = GTK_IMAGE(gtk_image_new_from_file("circles.xbm"));
+ gtk_box_pack_start(GTK_BOX (content_area), GTK_WIDGET(md->image), TRUE,TRUE, 0);
+ md->close_button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
+ g_signal_connect(md->close_button, "clicked",
+ G_CALLBACK (destroy), md->dialog);
+
+ gtk_box_pack_start(GTK_BOX (action_area), md->close_button, TRUE,TRUE, 0);
+
+ gtk_widget_show_all(md->dialog);
+ visibleDialog = 1;
+ }
+ }
+}
+
+
+static void
+_print_image_info(AtkObject *obj) {
+
+ gint height, width;
+ const gchar *desc;
+ const gchar *name = atk_object_get_name (obj);
+ const gchar *type_name = g_type_name(G_TYPE_FROM_INSTANCE (obj));
+
+ height = width = 0;
+
+
+ if(!ATK_IS_IMAGE(obj))
+ return;
+
+ g_print("atk_object_get_name : %s\n", name ? name : "<NULL>");
+ g_print("atk_object_get_type_name : %s\n",type_name ?type_name :"<NULL>");
+ g_print("*** Start Image Info ***\n");
+ desc = atk_image_get_image_description(ATK_IMAGE(obj));
+ g_print ("atk_image_get_image_desc returns : %s\n",desc ? desc:"<NULL>");
+ atk_image_get_image_size(ATK_IMAGE(obj), &height ,&width);
+ g_print("atk_image_get_image_size returns: height %d width %d\n",
+ height,width);
+ if(atk_image_set_image_description(ATK_IMAGE(obj),"New image Description")){
+ desc = atk_image_get_image_description(ATK_IMAGE(obj));
+ g_print ("atk_image_get_image_desc now returns : %s\n",desc?desc:"<NULL>");
+ }
+ g_print("*** End Image Info ***\n");
+
+
+}
+static void _traverse_children (AtkObject *obj)
+{
+ gint n_children, i;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ _print_image_info(child);
+ _traverse_children (child);
+ g_object_unref (G_OBJECT (child));
+ }
+}
+
+
+static void _check_objects (AtkObject *obj)
+{
+ AtkRole role;
+
+ g_print ("Start of _check_values\n");
+
+ _check_arrows(obj);
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME || role == ATK_ROLE_DIALOG)
+ {
+ /*
+ * Add handlers to all children.
+ */
+ _traverse_children (obj);
+ }
+ g_print ("End of _check_values\n");
+}
+
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_objects);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testimages Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "testlib.h"
+
+static gint _get_position_in_array (gint window,
+ gchar *the_test_name);
+static gint _get_position_in_parameters (gint window,
+ gchar *label,
+ gint position);
+static void _create_output_window (OutputWindow **outwin);
+static gboolean _create_select_tests_window (AtkObject *obj,
+ TLruntest runtest,
+ OutputWindow **outwin);
+static void _toggle_selectedcb (GtkWidget *widget,
+ gpointer test);
+static void _testselectioncb (GtkWidget *widget,
+ gpointer data);
+static void _destroy (GtkWidget *widget,
+ gpointer data);
+
+/* General functions */
+
+/**
+ * find_object_by_role:
+ * @obj: An #AtkObject
+ * @roles: An array of roles to search for
+ * @num_roles: The number of entries in @roles
+ *
+ * Find the #AtkObject which is a decendant of the specified @obj
+ * which is of an #AtkRole type specified in the @roles array.
+ *
+ * Returns: the #AtkObject that meets the specified criteria or NULL
+ * if no object is found.
+ **/
+AtkObject*
+find_object_by_role (AtkObject *obj,
+ AtkRole *roles,
+ gint num_roles)
+{
+ /*
+ * Find the first object which is a descendant of the specified object
+ * which matches the specified role.
+ *
+ * This function returns a reference to the AtkObject which should be
+ * removed when finished with the object.
+ */
+ gint i, j;
+ gint n_children;
+ AtkObject *child;
+
+ if (obj == NULL)
+ return NULL;
+
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (obj) == roles[j])
+ return obj;
+ }
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+
+ if (child == NULL)
+ continue;
+
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (child) == roles[j])
+ return child;
+ }
+
+ found_obj = find_object_by_role (child, roles, num_roles);
+ g_object_unref (child);
+ if (found_obj)
+ return found_obj;
+ }
+ return NULL;
+}
+
+/**
+ * find_object_by_name_and_role:
+ * @obj: An #AtkObject
+ * @name: The GTK widget name
+ * @roles: An array of roles to search for
+ * @num_roles: The number of entries in @roles
+ *
+ * Find the #AtkObject which is a decendant of the specified @obj
+ * which is of an #AtkRole type specified in the @roles array which
+ * also has the GTK widget name specified in @name.
+ *
+ * Returns: the #AtkObject that meets the specified criteria or NULL
+ * if no object is found.
+ **/
+AtkObject*
+find_object_by_name_and_role(AtkObject *obj,
+ const gchar *name,
+ AtkRole *roles,
+ gint num_roles)
+{
+ AtkObject *child;
+ GtkWidget* widget;
+ gint i, j;
+ gint n_children;
+
+ if (obj == NULL)
+ return NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ if (GTK_IS_WIDGET (widget))
+ {
+ if (strcmp (name, gtk_widget_get_name(GTK_WIDGET (widget))) == 0)
+ {
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (obj) == roles[j])
+ return obj;
+ }
+ }
+ }
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+
+ if (child == NULL)
+ continue;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (child));
+ if (GTK_IS_WIDGET (widget))
+ {
+ if (strcmp(name, gtk_widget_get_name(GTK_WIDGET (widget))) == 0)
+ {
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (child) == roles[j])
+ return child;
+ }
+ }
+ }
+ found_obj = find_object_by_name_and_role (child, name, roles, num_roles);
+ g_object_unref (child);
+ if (found_obj)
+ return found_obj;
+ }
+ return NULL;
+}
+
+/**
+ * find_object_by_accessible_name_and_role:
+ * @obj: An #AtkObject
+ * @name: The accessible name
+ * @roles: An array of roles to search for
+ * @num_roles: The number of entries in @roles
+ *
+ * Find the #AtkObject which is a decendant of the specified @obj
+ * which has the specified @name and matches one of the
+ * specified @roles.
+ *
+ * Returns: the #AtkObject that meets the specified criteria or NULL
+ * if no object is found.
+ */
+AtkObject*
+find_object_by_accessible_name_and_role (AtkObject *obj,
+ const gchar *name,
+ AtkRole *roles,
+ gint num_roles)
+{
+ AtkObject *child;
+ gint i, j;
+ gint n_children;
+ const gchar *accessible_name;
+
+ if (obj == NULL)
+ return NULL;
+
+ accessible_name = atk_object_get_name (obj);
+ if (accessible_name && (strcmp(name, accessible_name) == 0))
+ {
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (obj) == roles[j])
+ return obj;
+ }
+ }
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+
+ if (child == NULL)
+ continue;
+
+ accessible_name = atk_object_get_name (child);
+ if (accessible_name && (strcmp(name, accessible_name) == 0))
+ {
+ for (j=0; j < num_roles; j++)
+ {
+ if (atk_object_get_role (child) == roles[j])
+ return child;
+ }
+ }
+ found_obj = find_object_by_accessible_name_and_role (child, name,
+ roles, num_roles);
+ g_object_unref (child);
+ if (found_obj)
+ return found_obj;
+ }
+ return NULL;
+}
+
+/**
+ * find_object_by_name_and_role:
+ * @obj: An #AtkObject
+ * @type: The type
+ *
+ * Find the #AtkObject which is a decendant of the specified @obj
+ * which has the specified @type.
+ *
+ * Returns: the #AtkObject that meets the specified criteria or NULL
+ * if no object is found.
+ */
+AtkObject*
+find_object_by_type (AtkObject *obj,
+ gchar *type)
+{
+ /*
+ * Find the first object which is a descendant of the specified object
+ * which matches the specified type.
+ *
+ * This function returns a reference to the AtkObject which should be
+ * removed when finished with the object.
+ */
+ gint i;
+ gint n_children;
+ AtkObject *child;
+ const gchar * typename = NULL;
+
+ if (obj == NULL)
+ return NULL;
+
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ if (strcmp (typename, type) == 0)
+ return obj;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+
+ if (child == NULL)
+ continue;
+
+ typename = g_type_name (G_OBJECT_TYPE (child));
+
+ if (strcmp (typename, type) == 0)
+ return child;
+
+ found_obj = find_object_by_type (child, type);
+ g_object_unref (child);
+ if (found_obj)
+ return found_obj;
+ }
+ return NULL;
+}
+
+/**
+ * already_accessed_atk_object
+ * @obj: An #AtkObject
+ *
+ * Keeps a static GPtrArray of objects that have been passed into this
+ * function.
+ *
+ * Returns: TRUE if @obj has been passed into this function before
+ * and FALSE otherwise.
+ */
+gboolean
+already_accessed_atk_object (AtkObject *obj)
+{
+ static GPtrArray *obj_array = NULL;
+ gboolean found = FALSE;
+ gint i;
+
+ /*
+ * We create a property handler for each object if one was not associated
+ * with it already.
+ *
+ * We add it to our array of objects which have property handlers; if an
+ * object is destroyed it remains in the array.
+ */
+ if (obj_array == NULL)
+ obj_array = g_ptr_array_new ();
+
+ for (i = 0; i < obj_array->len; i++)
+ {
+ if (obj == g_ptr_array_index (obj_array, i))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ g_ptr_array_add (obj_array, obj);
+
+ return found;
+}
+
+/**
+ * display_children
+ * @obj: An #AtkObject
+ * @depth: Number of spaces to indent output.
+ * @child_number: The child number of this object.
+ *
+ * Displays the hierarchy of widgets starting from @obj.
+ **/
+void
+display_children (AtkObject *obj,
+ gint depth,
+ gint child_number)
+{
+ display_children_to_depth(obj, -1, depth, child_number);
+}
+
+/**
+ * display_children_to_depth
+ * @obj: An #AtkObject
+ * @to_depth: Display to this depth.
+ * @depth: Number of spaces to indent output.
+ * @child_number: The child number of this object.
+ *
+ * Displays the hierarchy of widgets starting from @obj only
+ * to the specified depth.
+ **/
+void
+display_children_to_depth (AtkObject *obj,
+ gint to_depth,
+ gint depth,
+ gint child_number)
+{
+ AtkRole role;
+ const gchar *rolename;
+ const gchar *typename;
+ gint n_children, parent_index, i;
+
+ if (to_depth >= 0 && depth > to_depth)
+ return;
+
+ if (obj == NULL)
+ return;
+
+ for (i=0; i < depth; i++)
+ g_print(" ");
+
+ role = atk_object_get_role (obj);
+ rolename = atk_role_get_name (role);
+
+ /*
+ * Note that child_number and parent_index should be the same
+ * unless there is an error.
+ */
+ parent_index = atk_object_get_index_in_parent(obj);
+ g_print("child <%d == %d> ", child_number, parent_index);
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ g_print ("children <%d> ", n_children);
+
+ if (rolename)
+ g_print("role <%s>, ", rolename);
+ else
+ g_print("role <error>");
+
+ if (GTK_IS_ACCESSIBLE(obj))
+ {
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ g_print("name <%s>, ", gtk_widget_get_name(GTK_WIDGET (widget)));
+ }
+ else
+ g_print("name <NULL>, ");
+
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("typename <%s>\n", typename);
+
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ if (child != NULL)
+ {
+ display_children_to_depth (child, to_depth, depth + 1, i);
+ g_object_unref (G_OBJECT (child));
+ }
+ }
+}
+
+/* Test GUI logic */
+
+/* GUI Information for the Select Tests Window */
+typedef struct
+{
+ GtkWidget *selecttestsWindow;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *textInsert;
+ GtkWidget *button;
+ gchar *selecttestsTitle;
+}MainDialog;
+
+/* Functionality information about each added test */
+typedef struct
+{
+ GtkWidget *toggleButton;
+ GtkWidget *hbox;
+ GtkWidget *parameterLabel[MAX_PARAMS];
+ GtkWidget *parameterInput[MAX_PARAMS];
+ gchar *testName;
+ gint numParameters;
+}TestList;
+
+typedef struct
+{
+ TLruntest runtest;
+ AtkObject* obj;
+ gint win_num;
+}TestCB;
+
+static MainDialog *md[MAX_WINDOWS];
+static OutputWindow *ow;
+
+/* An array containing function information on all of the tests */
+static TestList listoftests[MAX_WINDOWS][MAX_TESTS];
+
+/* A counter for the actual number of added tests */
+gint counter;
+
+/* A global for keeping track of the window numbers */
+static gint window_no = 0;
+/* An array containing the names of the tests that are "on" */
+static gchar *onTests[MAX_WINDOWS][MAX_TESTS];
+static gint g_visibleDialog = 0;
+static gint testcount[MAX_WINDOWS];
+static TestCB testcb[MAX_WINDOWS];
+
+/**
+ * create_windows:
+ * @obj: An #AtkObject
+ * @runtest: The callback function to run when the "Run Tests" button
+ * is clicked.
+ * @outwin: The output window to use. If NULL is passed in, then
+ * create a new one.
+ *
+ * Creates the test window and the output window (if @outwin is NULL)
+ * Runs _create_output_window() and _create_select_tests_window()
+ * and sets g_visibleDialog to 1
+ *
+ * Returns: The window number of the created window if successful, -1 otherwise.
+ **/
+gint
+create_windows (AtkObject *obj,
+ TLruntest runtest,
+ OutputWindow **outwin)
+{
+ gboolean valid;
+ gint tmp;
+
+ g_visibleDialog = 1;
+ _create_output_window(outwin);
+ valid = _create_select_tests_window(obj, runtest, outwin);
+ if (valid)
+ {
+ tmp = window_no;
+ window_no++;
+ return tmp;
+ }
+ else
+ return -1;
+}
+
+/**
+ * _create_output_window
+ * @outwin: If outwin is passed in as NULL, a new output window is created
+ * otherwise, the outwin passed in is shared.
+ *
+ * Creates the Test Result Output Window .
+ **/
+static void
+_create_output_window (OutputWindow **outwin)
+{
+ GtkWidget *view;
+ GtkWidget *scrolled_window;
+ OutputWindow *localow;
+
+ if (*outwin == NULL)
+ {
+ localow = (OutputWindow *) malloc (sizeof(OutputWindow));
+
+ localow->outputBuffer = gtk_text_buffer_new(NULL);
+ view = gtk_text_view_new_with_buffer(GTK_TEXT_BUFFER(localow->outputBuffer));
+ gtk_widget_set_size_request (view, 700, 500);
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD);
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);
+
+ localow->outputWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(localow->outputWindow), "Test Output");
+ scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(localow->outputWindow), scrolled_window);
+ gtk_container_add(GTK_CONTAINER(scrolled_window), view);
+ gtk_text_buffer_get_iter_at_offset(localow->outputBuffer, &localow->outputIter, 0);
+ gtk_widget_show(view);
+ gtk_widget_show(scrolled_window);
+ gtk_widget_show(localow->outputWindow);
+
+ gtk_text_buffer_set_text(GTK_TEXT_BUFFER(localow->outputBuffer),
+ "\n\nWelcome to the test GUI:\nTest results are printed here\n\n", 58);
+ gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(localow->outputBuffer),
+ &localow->outputIter, 0);
+ *outwin = localow;
+ ow = *outwin;
+ }
+}
+
+/**
+ * _create_select_tests_window:
+ * @obj: An #AtkObject
+ * @runtest: The callback function that is run when the "Run Tests"
+ * button is clicked.
+ * @outwin: The output window to use.
+ *
+ * Creates the Test Select Window
+ *
+ * Returns: TRUE if successful, FALSE otherwise
+ **/
+static gboolean
+_create_select_tests_window (AtkObject *obj,
+ TLruntest runtest,
+ OutputWindow **outwin)
+{
+ GtkWidget *hbuttonbox;
+ GtkWidget *scrolledWindow;
+
+ if (window_no >= 0 && window_no < MAX_WINDOWS)
+ {
+ md[window_no] = (MainDialog *) malloc (sizeof(MainDialog));
+
+ /* Setup Window */
+ md[window_no]->selecttestsTitle = "Test Setting";
+ md[window_no]->selecttestsWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW( ow->outputWindow),
+ md[window_no]->selecttestsTitle);
+ gtk_window_set_resizable (GTK_WINDOW(md[window_no]->selecttestsWindow),
+ FALSE);
+ gtk_window_set_position (GTK_WINDOW(md[window_no]->selecttestsWindow),
+ GTK_WIN_POS_CENTER);
+ g_signal_connect (md[window_no]->selecttestsWindow,
+ "destroy",
+ G_CALLBACK (_destroy),
+ &md[window_no]->selecttestsWindow);
+
+ /* Setup Scrolling */
+ scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledWindow),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_widget_set_size_request (scrolledWindow, 500, 600);
+ gtk_container_add (GTK_CONTAINER (md[window_no]->selecttestsWindow),
+ scrolledWindow);
+
+ /* Setup Layout */
+ md[window_no]->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_box_set_homogeneous (GTK_BOX (md[window_no]->vbox), TRUE);
+ md[window_no]->button = gtk_button_new_with_mnemonic ("_Run Tests");
+ hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox),
+ GTK_BUTTONBOX_SPREAD);
+ gtk_box_pack_end (GTK_BOX (hbuttonbox),
+ GTK_WIDGET (md[window_no]->button), TRUE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (md[window_no]->vbox), hbuttonbox,
+ TRUE, TRUE, 0);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolledWindow),
+ md[window_no]->vbox);
+
+ testcb[window_no].runtest = runtest;
+ testcb[window_no].obj = obj;
+ testcb[window_no].win_num = window_no;
+ g_signal_connect (md[window_no]->button,
+ "clicked",
+ G_CALLBACK (_testselectioncb),
+ (gpointer)&testcb[window_no]);
+
+ /* Show all */
+ gtk_widget_grab_focus (md[window_no]->button);
+ gtk_widget_show (md[window_no]->button);
+ gtk_widget_show (hbuttonbox);
+ gtk_widget_show (scrolledWindow);
+ gtk_widget_show_all (GTK_WIDGET (md[window_no]->selecttestsWindow));
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/**
+ * add_test
+ * @window: The window number
+ * @name: The test name
+ * @num_params: The number of arguments the test uses.
+ * @parameter_names: The names of each argument.
+ * @default_names: The default values of each argument.
+ *
+ * Adds a Test with the passed-in details to the Tests Select Window.
+ *
+ * Returns: FALSE if the num_params passed in is greater than
+ * MAX_PARAMS, otherwise returns TRUE
+ *
+ **/
+gboolean
+add_test (gint window,
+ gchar *name,
+ gint num_params,
+ gchar* parameter_names[],
+ gchar* default_names[])
+{
+ gint i;
+
+ if (num_params > MAX_PARAMS)
+ return FALSE;
+ else
+ {
+ md[window]->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_set_spacing (GTK_BOX (md[window]->hbox), 10);
+ gtk_container_set_border_width (GTK_CONTAINER (md[window]->hbox), 10);
+ gtk_container_add (GTK_CONTAINER (md[window]->vbox), md[window]->hbox);
+ listoftests[window][testcount[window]].toggleButton =
+ gtk_toggle_button_new_with_label (name);
+ gtk_box_pack_start (GTK_BOX (md[window]->hbox),
+ listoftests[window][testcount[window]].toggleButton, FALSE, FALSE, 0);
+ listoftests[window][testcount[window]].testName = name;
+ listoftests[window][testcount[window]].numParameters = num_params;
+ for (i=0; i<num_params; i++)
+ {
+ listoftests[window][testcount[window]].parameterLabel[i] =
+ gtk_label_new (parameter_names[i]);
+ gtk_box_pack_start (GTK_BOX (md[window]->hbox),
+ listoftests[window][testcount[window]].parameterLabel[i], FALSE, FALSE, 0);
+ listoftests[window][testcount[window]].parameterInput[i] = gtk_entry_new();
+ gtk_entry_set_text (GTK_ENTRY (listoftests[window][testcount[window]].parameterInput[i]),
+ default_names[i]);
+ gtk_widget_set_size_request (listoftests[window][testcount[window]].parameterInput[i], 50, 22);
+ gtk_box_pack_start (GTK_BOX (md[window]->hbox),
+ listoftests[window][testcount[window]].parameterInput[i], FALSE, FALSE, 0);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (listoftests[window][testcount[window]].parameterLabel[i]), FALSE);
+ gtk_widget_set_sensitive (
+ GTK_WIDGET (listoftests[window][testcount[window]].parameterInput[i]), FALSE);
+ gtk_widget_show (listoftests[window][testcount[window]].parameterLabel[i]);
+ gtk_widget_show (listoftests[window][testcount[window]].parameterInput[i]);
+ }
+ g_signal_connect (listoftests[window][testcount[window]].toggleButton,
+ "toggled",
+ G_CALLBACK (_toggle_selectedcb),
+ (gpointer)&(listoftests[window][testcount[window]]));
+ gtk_widget_show (listoftests[window][testcount[window]].toggleButton);
+ gtk_widget_show (md[window]->hbox);
+ gtk_widget_show (md[window]->vbox);
+
+ testcount[window]++;
+ counter++;
+ return TRUE;
+ }
+}
+
+/**
+ * tests_set:
+ * @window: The window number
+ * @count: Passes back the number of tests on.
+ *
+ * Gets an array of strings corresponding to the tests that are "on".
+ * A test is assumed on if the toggle button is on and if all its
+ * parameters have values.
+ *
+ * Returns: an array of strings corresponding to the tests that
+ * are "on".
+ **/
+gchar **tests_set(gint window, int *count)
+{
+ gint i =0, j = 0, num;
+ gboolean nullparam;
+ gchar* input;
+
+ *count = 0;
+ for (i = 0; i < MAX_TESTS; i++)
+ onTests[window][i] = NULL;
+
+ for (i = 0; i < testcount[window]; i++)
+ {
+ nullparam = FALSE;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (listoftests[window][i].toggleButton)))
+ {
+ num = listoftests[window][i].numParameters;
+ for (j = 0; j < num; j++)
+ {
+ input = gtk_editable_get_chars (
+ GTK_EDITABLE (listoftests[window][i].parameterInput[j]), 0, -1);
+
+ if (input != NULL && (! strcmp(input, "")))
+ nullparam = TRUE;
+ }
+ if (!nullparam)
+ {
+ onTests[window][*count] = listoftests[window][i].testName;
+ *count = *count + 1;
+ }
+ }
+ }
+ return onTests[window];
+}
+
+/**
+ * _get_position_in_array:
+ * @window: The window number
+ * @the_test_name: The name of the test
+ *
+ * Gets the index of the passed-in @the_test_name.
+ *
+ * Returns: the position in listoftests[] of @the_test_name
+ **/
+static gint
+_get_position_in_array(gint window,
+ gchar *the_test_name)
+{
+ gint i;
+
+ for (i = 0; i < testcount[window]; i++)
+ {
+ if (strcmp(listoftests[window][i].testName, the_test_name) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/**
+ * _get_position_in_parameters:
+ * @window: The window number
+ * @label: The label name
+ * @position: The parameter position
+ *
+ * Gets the index of the passed-in parameter @label.
+ *
+ * Returns: the position in parameterLabel[] (a member of
+ * listoftests[]) of @label
+ **/
+static gint
+_get_position_in_parameters(gint window,
+ gchar *label,
+ gint position)
+{
+ gint i;
+ const gchar *label_string;
+
+ for (i = 0; i < MAX_PARAMS; i++)
+ {
+ label_string = gtk_label_get_text(
+ GTK_LABEL (listoftests[window][position].parameterLabel[i]));
+
+ if (strcmp(label_string, label) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/**
+ * set_output_buffer:
+ * @output: The string to add to the output buffer
+ *
+ * Tidies up the output Window
+ **/
+void
+set_output_buffer(gchar *output)
+{
+ gtk_text_buffer_insert (GTK_TEXT_BUFFER (ow->outputBuffer),
+ &ow->outputIter, output, strlen(output));
+ gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (ow->outputBuffer),
+ &ow->outputIter, 0);
+}
+
+/**
+ * isVisibleDialog:
+ *
+ * Informs user if a visible test window running.
+ *
+ * Returns: TRUE if g_visibleDialog is set to 1, otherwise FALSE
+ **/
+gboolean
+isVisibleDialog(void)
+{
+ if (g_visibleDialog >= 1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/**
+ * get_arg_of_func:
+ * @window: The window number
+ * @function_name: The name of the function
+ * @arg_label: The label of the argument.
+ *
+ * Gets the user input associated with the @function_name and @arg_label.
+ *
+ * Returns: the user input associated with the @function_name and @arg_label.
+ **/
+gchar*
+get_arg_of_func (gint window,
+ gchar *function_name,
+ gchar *arg_label)
+{
+ const gchar *argString;
+ gchar *retString;
+ gint position, paramPosition;
+
+ position = _get_position_in_array(window, function_name);
+
+ if (position == -1)
+ {
+ g_print("No such function\n");
+ return NULL;
+ }
+
+ paramPosition = _get_position_in_parameters(window, arg_label, position);
+
+ if (paramPosition == -1)
+ {
+ g_print("No such parameter Label\n");
+ return NULL;
+ }
+
+ if (position != -1 && paramPosition != -1)
+ {
+ argString = gtk_editable_get_chars (
+ GTK_EDITABLE (listoftests[window][position].parameterInput[paramPosition]),
+ 0, -1);
+ retString = g_strdup(argString);
+ }
+ else
+ retString = NULL;
+
+ return retString;
+}
+
+/**
+ * string_to_int:
+ * @the_string: The string to convert
+ *
+ * Converts the passed-in string to an integer
+ *
+ * Returns: An integer corresponding to @the_string.
+ **/
+int
+string_to_int (const char *the_string)
+{
+ char *end_ptr;
+ double ret_val;
+ int int_ret_val;
+
+ while (1)
+ {
+ ret_val = strtod( the_string, &end_ptr);
+ if (*end_ptr == '\0')
+ break;
+ else
+ printf("\nError: input must be a number\n");
+ }
+
+ int_ret_val = (int) ret_val;
+ return (int_ret_val);
+}
+
+/**
+ * _toggle_selectedcb:
+ * @widget: The ToggleButton widget
+ * @test: user data containing the TestList structure.
+ *
+ * Toggle Button Callback, activating the text entry fields
+ **/
+static void
+_toggle_selectedcb (GtkWidget *widget,
+ gpointer test)
+{
+ int i;
+ TestList *testlist = (TestList *) test;
+ gboolean toggled;
+ gboolean sensitive;
+ toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ if (toggled)
+ sensitive = TRUE;
+ else
+ sensitive = FALSE;
+
+ for (i=0; i < testlist->numParameters; i++)
+ {
+ gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterLabel[i]),
+ sensitive);
+ gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterInput[i]),
+ sensitive);
+ }
+}
+
+/*
+ * _testselectioncb:
+ * widget: The Button widget
+ * data: The user data containing a TestCB structure
+ *
+ * Callback for when the "Run Tests" button is pressed
+ **/
+static void
+_testselectioncb (GtkWidget *widget,
+ gpointer data)
+{
+ TestCB* local_testcb = (TestCB *)data;
+ local_testcb->runtest(local_testcb->obj, local_testcb->win_num);
+}
+
+/**
+ * _destroy:
+ * @widget: The GUI widget
+ * @data: User data, not used.
+ *
+ * Destroy Callback.
+ **/
+static void
+_destroy (GtkWidget *widget,
+ gpointer data)
+{
+ gtk_main_quit();
+}
+
--- /dev/null
+#include <stdio.h>
+#include <gtk/gtk.h>
+
+/* Maximum characters in the output buffer */
+#define MAX_LINE_SIZE 1000
+
+/* Maximum number of tests */
+#define MAX_TESTS 30
+
+/* Maximum number of test windows */
+#define MAX_WINDOWS 5
+
+/* Maximum number of parameters any test can have */
+#define MAX_PARAMS 3
+
+/* Information on the Output Window */
+
+typedef struct
+{
+ GtkWidget *outputWindow;
+ GtkTextBuffer *outputBuffer;
+ GtkTextIter outputIter;
+}OutputWindow;
+
+typedef void (*TLruntest) (AtkObject * obj, gint win_num);
+
+/* General purpose functions */
+
+gboolean already_accessed_atk_object (AtkObject *obj);
+AtkObject* find_object_by_role (AtkObject *obj,
+ AtkRole *role,
+ gint num_roles);
+AtkObject* find_object_by_type (AtkObject *obj,
+ gchar *type);
+AtkObject* find_object_by_name_and_role (AtkObject *obj,
+ const gchar *name,
+ AtkRole *roles,
+ gint num_roles);
+AtkObject* find_object_by_accessible_name_and_role (AtkObject *obj,
+ const gchar *name,
+ AtkRole *roles,
+ gint num_roles);
+void display_children (AtkObject *obj,
+ gint depth,
+ gint child_number);
+void display_children_to_depth (AtkObject *obj,
+ gint to_depth,
+ gint depth,
+ gint child_number);
+
+
+/* Test GUI functions */
+
+gint create_windows (AtkObject *obj,
+ TLruntest runtest,
+ OutputWindow **outwin);
+gboolean add_test (gint window,
+ gchar *name,
+ gint num_params,
+ gchar *parameter_names[],
+ gchar *default_names[]);
+void set_output_buffer (gchar *output);
+gchar **tests_set (gint window,
+ int *count);
+gchar *get_arg_of_func (gint window,
+ gchar *function_name,
+ gchar *arg_label);
+int string_to_int (const char *the_string);
+gboolean isVisibleDialog (void);
+
--- /dev/null
+#include <string.h>
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+/*
+ * This module is used to test the accessible implementation for menu items
+ *
+ * 1) When a menu item is clicked in testgtk, the action for the
+ * item is performed.
+ * 2) The name of the keybinding for the 'activate" action for a menu item
+ * is output, if it exists.
+ * 3) Execute the action for a menu item programatically
+ */
+#define NUM_VALID_ROLES 1
+
+static void _create_event_watcher (void);
+static void _check_object (AtkObject *obj);
+static gint _do_menu_item_action (gpointer data);
+
+static void
+_check_object (AtkObject *obj)
+{
+ AtkRole role;
+ static const char *name = NULL;
+ static gboolean first_time = TRUE;
+
+ role = atk_object_get_role (obj);
+ if (role == ATK_ROLE_FRAME)
+ /*
+ * Find the specified menu item
+ */
+ {
+ AtkRole valid_roles[NUM_VALID_ROLES];
+ AtkObject *atk_menu_item;
+ GtkWidget *widget;
+
+ if (name == NULL)
+ {
+ valid_roles[0] = ATK_ROLE_MENU_ITEM;
+
+ name = g_getenv ("TEST_ACCESSIBLE_NAME");
+ if (name == NULL)
+ name = "foo";
+ }
+ atk_menu_item = find_object_by_accessible_name_and_role (obj, name,
+ valid_roles, NUM_VALID_ROLES);
+
+ if (atk_menu_item == NULL)
+ {
+ g_print ("Object not found for %s\n", name);
+ return;
+ }
+
+ g_assert (GTK_IS_ACCESSIBLE (atk_menu_item));
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_menu_item));
+ g_assert (GTK_IS_MENU_ITEM (widget));
+
+ if (first_time)
+ first_time = FALSE;
+ else
+ return;
+
+ /*
+ * This action opens the menu whose name is "foo" or whatever
+ * was specified in the environment variable TEST_ACCESSIBLE_NAME
+ */
+ atk_action_do_action (ATK_ACTION (atk_menu_item), 0);
+ }
+ else if ((role == ATK_ROLE_MENU_ITEM) ||
+ (role == ATK_ROLE_CHECK_MENU_ITEM) ||
+ (role == ATK_ROLE_RADIO_MENU_ITEM) ||
+ (role == ATK_ROLE_TEAR_OFF_MENU_ITEM))
+ {
+ const char *keybinding;
+ const char *accessible_name;
+
+ accessible_name = atk_object_get_name (obj);
+ if (accessible_name)
+ g_print ("Name: %s\n", accessible_name);
+ g_print ("Action: %s\n", atk_action_get_name (ATK_ACTION (obj), 0));
+ keybinding = atk_action_get_keybinding (ATK_ACTION (obj), 0);
+ if (keybinding)
+ g_print ("KeyBinding: %s\n", keybinding);
+ /*
+ * Do the action associated with the menu item once, otherwise
+ * we get into a loop
+ */
+ if (strcmp (name, accessible_name) == 0)
+ {
+ if (first_time)
+ first_time = FALSE;
+ else
+ return;
+ if (g_getenv ("TEST_ACCESSIBLE_AUTO"))
+ {
+ g_idle_add (_do_menu_item_action, obj);
+ }
+ }
+ }
+ else
+ {
+ const char *accessible_name;
+
+ accessible_name = atk_object_get_name (obj);
+ if (accessible_name)
+ g_print ("Name: %s\n", accessible_name);
+ else if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget *widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ g_print ("Type: %s\n", g_type_name (G_OBJECT_TYPE (widget)));
+ }
+ }
+}
+
+static gint _do_menu_item_action (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+
+ atk_action_do_action (ATK_ACTION (obj), 0);
+
+ return FALSE;
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_object);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testmenuitem Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+#include <glib.h>
+#include <atk/atk.h>
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+#define NUM_VALID_ROLES 1
+
+static void _print_type (AtkObject *obj);
+static void _do_selection (AtkObject *obj);
+static gint _finish_selection (gpointer data);
+static gint _remove_page (gpointer data);
+
+static void _print_type (AtkObject *obj)
+{
+ const gchar *typename = NULL;
+ const gchar *name = NULL;
+ const gchar *description = NULL;
+ AtkRole role;
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget* widget = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ typename = g_type_name (G_OBJECT_TYPE (widget));
+ g_print ("\tWidget type name: %s\n", typename ? typename : "NULL");
+ }
+
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("\tAccessible type name: %s\n", typename ? typename : "NULL");
+
+ name = atk_object_get_name (obj);
+ g_print("\tAccessible Name: %s\n", (name) ? name : "NULL");
+
+ role = atk_object_get_role(obj);
+ g_print ("\tAccessible Role: %d\n", role);
+
+ description = atk_object_get_description (obj);
+ g_print ("\tAccessible Description: %s\n", (description) ? description : "NULL");
+ if (role == ATK_ROLE_PAGE_TAB)
+ {
+ AtkObject *parent, *child;
+ gint x, y, width, height;
+
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (obj), &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_print ("obj: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (obj), &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("obj: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+ parent = atk_object_get_parent (obj);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (parent), &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_print ("parent: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (parent), &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("parent: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+
+ child = atk_object_ref_accessible_child (obj, 0);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (child), &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_print ("child: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+ x = y = width = height = 0;
+ atk_component_get_extents (ATK_COMPONENT (child), &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("child: x: %d y: %d width: %d height: %d\n", x, y, width, height);
+
+ g_object_unref (child);
+ }
+}
+
+
+static void
+_do_selection (AtkObject *obj)
+{
+ gint i;
+ gint n_children;
+ AtkRole role;
+ AtkObject *selection_obj;
+ static gboolean done_selection = FALSE;
+
+ if (done_selection)
+ return;
+
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME)
+ {
+ AtkRole roles[NUM_VALID_ROLES];
+
+ roles[0] = ATK_ROLE_PAGE_TAB_LIST;
+
+ selection_obj = find_object_by_role (obj, roles, NUM_VALID_ROLES);
+
+ if (selection_obj)
+ {
+ done_selection = TRUE;
+ }
+ else
+ return;
+ }
+ else
+ {
+ return;
+ }
+
+ g_print ("*** Start do_selection ***\n");
+
+ n_children = atk_object_get_n_accessible_children (selection_obj);
+ g_print ("*** Number of notebook pages: %d\n", n_children);
+
+ for (i = 0; i < n_children; i++)
+ {
+ if (atk_selection_is_child_selected (ATK_SELECTION (selection_obj), i))
+ {
+ g_print ("%d page selected\n", i);
+ }
+ else
+ {
+ g_print ("%d page not selected\n", i);
+ }
+ }
+ /*
+ * Should not be able to select all items in a notebook.
+ */
+ atk_selection_select_all_selection (ATK_SELECTION (selection_obj));
+ i = atk_selection_get_selection_count (ATK_SELECTION (selection_obj));
+ if ( i != 1)
+ {
+ g_print ("Unexpected selection count: %d, expected 1\n", i);
+ g_print ("\t value of i is: %d\n", i);
+ return;
+ }
+
+ for (i = 0; i < n_children; i++)
+ {
+ atk_selection_add_selection (ATK_SELECTION (selection_obj), i);
+
+ if (atk_selection_is_child_selected (ATK_SELECTION (selection_obj), i))
+ {
+ g_print ("Page %d: successfully selected\n", i);
+ _finish_selection (selection_obj);
+ }
+ else
+ {
+ g_print ("ERROR: child %d: selection failed\n", i);
+ }
+ }
+ g_print ("*** End _do_selection ***\n");
+ g_timeout_add (5000, _remove_page, selection_obj);
+}
+
+static gint _remove_page (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+ GtkWidget *widget = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+
+ g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (widget), 4);
+ return FALSE;
+}
+
+static gint _finish_selection (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+ AtkObject *selected;
+ AtkObject *parent_object;
+ GtkWidget *parent_widget;
+ gint i, index;
+
+ g_print ("\t*** Start Finish selection ***\n");
+
+ i = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ if (i != 1)
+ {
+ g_print ("\tUnexpected selection count: %d, expected 1\n", i);
+ return FALSE;
+ }
+ selected = atk_selection_ref_selection (ATK_SELECTION (obj), 0);
+ g_return_val_if_fail (selected != NULL, FALSE);
+
+ g_print ("\t*** Selected Item ***\n");
+ index = atk_object_get_index_in_parent (selected);
+ g_print ("\tIndex in parent is: %d\n", index);
+
+ parent_object = atk_object_get_parent (selected);
+ g_return_val_if_fail (ATK_IS_OBJECT (parent_object), FALSE);
+ g_return_val_if_fail (parent_object == obj, FALSE);
+ parent_widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent_object));
+ g_return_val_if_fail (GTK_IS_NOTEBOOK (parent_widget), FALSE);
+
+ _print_type (selected);
+ i = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_val_if_fail (i == 1, FALSE);
+ g_object_unref (selected);
+ g_print ("\t*** End Finish selection ***\n");
+ return FALSE;
+}
+
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_do_selection);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testnotebook Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+static void _print_accessible (AtkObject *obj);
+static void _print_type (AtkObject *obj);
+static void _print_states (AtkObject *obj);
+static void _check_children (AtkObject *obj);
+static void _check_relation (AtkObject *obj);
+static void _create_event_watcher (void);
+static void _focus_handler (AtkObject *obj, gboolean focus_in);
+static gboolean _children_changed (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+
+static guint id;
+
+static void _print_states (AtkObject *obj)
+{
+ AtkStateSet *state_set;
+ gint i;
+
+ state_set = atk_object_ref_state_set (obj);
+
+ g_print ("*** Start states ***\n");
+ for (i = 0; i < 64; i++)
+ {
+ AtkStateType one_state;
+ const gchar *name;
+
+ if (atk_state_set_contains_state (state_set, i))
+ {
+ one_state = i;
+
+ name = atk_state_type_get_name (one_state);
+
+ if (name)
+ g_print("%s\n", name);
+ }
+ }
+ g_object_unref (state_set);
+ g_print ("*** End states ***\n");
+}
+
+static void _print_type (AtkObject *obj)
+{
+ const gchar * typename = NULL;
+ const gchar * name = NULL;
+ AtkRole role;
+ static gboolean in_print_type = FALSE;
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget* widget = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ typename = g_type_name (G_OBJECT_TYPE (widget));
+ g_print ("Widget type name: %s\n", typename ? typename : "NULL");
+ }
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("Accessible type name: %s\n", typename ? typename : "NULL");
+ name = atk_object_get_name (obj);
+ g_print("Accessible Name: %s\n", (name) ? name : "NULL");
+ role = atk_object_get_role (obj);
+ g_print ("Accessible Role: %s\n", atk_role_get_name (role));
+
+ if (ATK_IS_COMPONENT (obj))
+ {
+ gint x, y, width, height;
+ AtkStateSet *states;
+
+ _print_states (obj);
+ states = atk_object_ref_state_set (obj);
+ if (atk_state_set_contains_state (states, ATK_STATE_VISIBLE))
+ {
+ AtkObject *parent;
+
+ atk_component_get_extents (ATK_COMPONENT (obj),
+ &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_print ("ATK_XY_SCREEN: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+
+ atk_component_get_extents (ATK_COMPONENT (obj),
+ &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("ATK_XY_WINDOW: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ if (atk_state_set_contains_state (states, ATK_STATE_SHOWING) &&
+ ATK_IS_TEXT (obj))
+ {
+ gint offset;
+
+ atk_text_get_character_extents (ATK_TEXT (obj), 1,
+ &x, &y, &width, &height,
+ ATK_XY_WINDOW);
+ g_print ("Character extents : %d %d %d %d\n",
+ x, y, width, height);
+ if (width != 0 && height != 0)
+ {
+ offset = atk_text_get_offset_at_point (ATK_TEXT (obj),
+ x, y,
+ ATK_XY_WINDOW);
+ if (offset != 1)
+ {
+ g_print ("Wrong offset returned (%d) %d\n", 1, offset);
+ }
+ }
+ }
+ if (in_print_type)
+ return;
+
+ parent = atk_object_get_parent (obj);
+ if (!ATK_IS_COMPONENT (parent))
+ {
+ /* Assume toplevel */
+ g_object_unref (G_OBJECT (states));
+ return;
+ }
+#if 0
+ obj1 = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
+ x, y, ATK_XY_WINDOW);
+ if (obj != obj1)
+ {
+ g_print ("Inconsistency between object and ref_accessible_at_point\n");
+ in_print_type = TRUE;
+ _print_type (obj1);
+ in_print_type = FALSE;
+ }
+#endif
+ }
+ g_object_unref (G_OBJECT (states));
+ }
+}
+
+static void _print_accessible (AtkObject *obj)
+{
+ GtkWidget* widget = NULL;
+ AtkObject* parent_atk;
+ AtkObject* ref_obj;
+ AtkRole role;
+ static gboolean first_time = TRUE;
+
+ if (first_time)
+ {
+ first_time = FALSE;
+ atk_add_global_event_listener (_children_changed,
+ "Atk:AtkObject:children_changed");
+ }
+
+ /*
+ * Check that the object returned by the atk_implementor_ref_accessible()
+ * for a widget is the same as the accessible object
+ */
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ ref_obj = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (widget));
+ g_assert (ref_obj == obj);
+ g_object_unref (G_OBJECT (ref_obj));
+ }
+ /*
+ * Add a focus handler so we see focus out events as well
+ */
+ if (ATK_IS_COMPONENT (obj))
+ atk_component_add_focus_handler (ATK_COMPONENT (obj), _focus_handler);
+ g_print ("Object:\n");
+ _print_type (obj);
+ _print_states (obj);
+
+ /*
+ * Get the parent object
+ */
+ parent_atk = atk_object_get_parent (obj);
+ if (parent_atk)
+ {
+ g_print ("Parent Object:\n");
+ _print_type (parent_atk);
+ parent_atk = atk_object_get_parent (parent_atk);
+ if (parent_atk)
+ {
+ g_print ("Grandparent Object:\n");
+ _print_type (parent_atk);
+ }
+ }
+ else
+ {
+ g_print ("No parent\n");
+ }
+
+ role = atk_object_get_role (obj);
+
+ if ((role == ATK_ROLE_FRAME) || (role == ATK_ROLE_DIALOG))
+ {
+ _check_children (obj);
+ }
+}
+
+static void _check_relation (AtkObject *obj)
+{
+ AtkRelationSet* relation_set = atk_object_ref_relation_set (obj);
+ gint n_relations, i;
+
+ g_return_if_fail (relation_set);
+
+ n_relations = atk_relation_set_get_n_relations (relation_set);
+ for (i = 0; i < n_relations; i++)
+ {
+ AtkRelation* relation = atk_relation_set_get_relation (relation_set, i);
+
+ g_print ("Index: %d Relation type: %d Number: %d\n", i,
+ atk_relation_get_relation_type (relation),
+ atk_relation_get_target (relation)->len);
+ }
+ g_object_unref (relation_set);
+}
+
+static void _check_children (AtkObject *obj)
+{
+ gint n_children, i;
+ AtkLayer layer;
+ AtkRole role;
+
+ g_print ("Start Check Children\n");
+ n_children = atk_object_get_n_accessible_children (obj);
+ g_print ("Number of children: %d\n", n_children);
+
+ role = atk_object_get_role (obj);
+
+ if (ATK_IS_COMPONENT (obj))
+ {
+ atk_component_add_focus_handler (ATK_COMPONENT (obj), _focus_handler);
+ layer = atk_component_get_layer (ATK_COMPONENT (obj));
+ if (role == ATK_ROLE_MENU)
+ g_assert (layer == ATK_LAYER_POPUP);
+ else
+ g_print ("Layer: %d\n", layer);
+ }
+
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+ AtkObject *parent;
+ int j;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ parent = atk_object_get_parent (child);
+ j = atk_object_get_index_in_parent (child);
+ _print_type (child);
+ _check_relation (child);
+ _check_children (child);
+ if (obj != parent)
+ {
+ g_print ("*** Inconsistency between atk_object_get_parent() and "
+ "atk_object_ref_accessible_child() ***\n");
+ _print_type (child);
+ _print_type (obj);
+ if (parent)
+ _print_type (parent);
+ }
+ g_object_unref (G_OBJECT (child));
+
+ if (j != i)
+ g_print ("*** Inconsistency between parent and children %d %d ***\n",
+ i, j);
+ }
+ g_print ("End Check Children\n");
+}
+
+static gboolean
+_children_changed (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ guint index;
+ gpointer target;
+ const gchar *target_name = "NotAtkObject";
+
+ object = g_value_get_object (param_values + 0);
+ index = g_value_get_uint (param_values + 1);
+ target = g_value_get_pointer (param_values + 2);
+ if (G_IS_OBJECT (target))
+ {
+ if (ATK_IS_OBJECT (target))
+ {
+ target_name = atk_object_get_name (target);
+ }
+ if (!target_name)
+ target_name = g_type_name (G_OBJECT_TYPE (G_OBJECT (target)));
+ }
+ else
+ {
+ if (!target)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (ATK_OBJECT (object), index);
+ if (child)
+ {
+ target_name = g_type_name (G_OBJECT_TYPE (G_OBJECT (child)));
+ g_object_unref (child);
+ }
+ }
+ }
+ g_print ("_children_watched: %s %s %s index: %d\n",
+ g_type_name (G_OBJECT_TYPE (object)),
+ g_quark_to_string (ihint->detail),
+ target_name, index);
+ return TRUE;
+}
+
+static void
+_create_event_watcher (void)
+{
+ /*
+ * _print_accessible() will be called for an accessible object when its
+ * widget receives focus.
+ */
+ id = atk_add_focus_tracker (_print_accessible);
+}
+
+static void
+_focus_handler (AtkObject *obj, gboolean focus_in)
+{
+ g_print ("In _focus_handler focus_in: %s\n", focus_in ? "true" : "false");
+ _print_type (obj);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testobject Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <testlib.h>
+
+static gint _test_paned (gpointer data);
+static void _check_paned (AtkObject *obj);
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+#define NUM_VALID_ROLES 1
+static gint last_position;
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ const gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
+ const gchar *name = atk_object_get_name (obj);
+
+ g_print ("_property_change_handler: Accessible Type: %s\n",
+ type_name ? type_name : "NULL");
+ g_print ("_property_change_handler: Accessible name: %s\n",
+ name ? name : "NULL");
+ g_print ("_property_change_handler: PropertyName: %s\n",
+ values->property_name ? values->property_name: "NULL");
+ if (strcmp (values->property_name, "accessible-value") == 0)
+ {
+ GValue *value, val;
+ int position;
+ value = &val;
+
+ memset (value, 0, sizeof (GValue));
+ atk_value_get_current_value (ATK_VALUE (obj), value);
+ g_return_if_fail (G_VALUE_HOLDS_INT (value));
+ position = g_value_get_int (value);
+ g_print ("Position is %d previous position was %d\n",
+ position, last_position);
+ last_position = position;
+ atk_value_get_minimum_value (ATK_VALUE (obj), value);
+ g_return_if_fail (G_VALUE_HOLDS_INT (value));
+ position = g_value_get_int (value);
+ g_print ("Minimum Value is %d\n", position);
+ atk_value_get_maximum_value (ATK_VALUE (obj), value);
+ g_return_if_fail (G_VALUE_HOLDS_INT (value));
+ position = g_value_get_int (value);
+ g_print ("Maximum Value is %d\n", position);
+ }
+}
+
+static gint _test_paned (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+ AtkRole role = atk_object_get_role (obj);
+ static gint times = 0;
+
+ if (role == ATK_ROLE_SPLIT_PANE)
+ {
+ GValue *value, val;
+ int position;
+ value = &val;
+
+ memset (value, 0, sizeof (GValue));
+ atk_value_get_current_value (ATK_VALUE (obj), value);
+ g_return_val_if_fail (G_VALUE_HOLDS_INT (value), FALSE);
+ position = g_value_get_int (value);
+ g_print ("Position is : %d\n", position);
+ last_position = position;
+ position *= 2;
+ g_value_set_int (value, position);
+ atk_value_set_current_value (ATK_VALUE (obj), value);
+ times++;
+ }
+ if (times < 4)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void _check_paned (AtkObject *obj)
+{
+ static gboolean done_paned = FALSE;
+ AtkRole role;
+
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME)
+ {
+ AtkRole roles[NUM_VALID_ROLES];
+ AtkObject *paned_obj;
+
+ if (done_paned)
+ return;
+
+ roles[0] = ATK_ROLE_SPLIT_PANE;
+
+ paned_obj = find_object_by_role (obj, roles, NUM_VALID_ROLES);
+
+ if (paned_obj)
+ {
+ if (!done_paned)
+ {
+ done_paned = TRUE;
+ }
+ atk_object_connect_property_change_handler (paned_obj,
+ (AtkPropertyChangeHandler*) _property_change_handler);
+ g_timeout_add (2000, _test_paned, paned_obj);
+ }
+
+ return;
+ }
+ if (role != ATK_ROLE_COMBO_BOX)
+ return;
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_paned);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testpaned Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include <atk/atk.h>
+#include <gtk/gtk.h>
+#include <testlib.h>
+
+static void _traverse_children (AtkObject *obj);
+static void _add_handler (AtkObject *obj);
+static void _check_properties (AtkObject *obj);
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+static void _state_changed (AtkObject *obj,
+ const gchar *name,
+ gboolean set);
+static void _selection_changed (AtkObject *obj);
+static void _visible_data_changed (AtkObject *obj);
+static void _model_changed (AtkObject *obj);
+static void _create_event_watcher (void);
+
+static guint id;
+
+static void
+_state_changed (AtkObject *obj,
+ const gchar *name,
+ gboolean set)
+{
+ g_print ("_state_changed: %s: state %s %s\n",
+ g_type_name (G_OBJECT_TYPE (obj)),
+ set ? "is" : "was", name);
+}
+
+static void
+_selection_changed (AtkObject *obj)
+{
+ gchar *type;
+
+ if (ATK_IS_TEXT (obj))
+ type = "text";
+ else if (ATK_IS_SELECTION (obj))
+ type = "child selection";
+ else
+ {
+ g_assert_not_reached();
+ return;
+ }
+
+ g_print ("In selection_changed signal handler for %s, object type: %s\n",
+ type, g_type_name (G_OBJECT_TYPE (obj)));
+}
+
+static void
+_visible_data_changed (AtkObject *obj)
+{
+ g_print ("In visible_data_changed signal handler, object type: %s\n",
+ g_type_name (G_OBJECT_TYPE (obj)));
+}
+
+static void
+_model_changed (AtkObject *obj)
+{
+ g_print ("In model_changed signal handler, object type: %s\n",
+ g_type_name (G_OBJECT_TYPE (obj)));
+}
+
+static void
+_property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ const gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
+ const gchar *name = atk_object_get_name (obj);
+
+ g_print ("_property_change_handler: Accessible Type: %s\n",
+ type_name ? type_name : "NULL");
+ g_print ("_property_change_handler: Accessible name: %s\n",
+ name ? name : "NULL");
+ g_print ("_property_change_handler: PropertyName: %s\n",
+ values->property_name ? values->property_name: "NULL");
+ if (G_VALUE_HOLDS_STRING (&values->new_value))
+ g_print ("_property_change_handler: PropertyValue: %s\n",
+ g_value_get_string (&values->new_value));
+ else if (strcmp (values->property_name, "accessible-child") == 0)
+ {
+ if (G_IS_VALUE (&values->old_value))
+ {
+ g_print ("Child is removed: %s\n",
+ g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->old_value))));
+ }
+ if (G_IS_VALUE (&values->new_value))
+ {
+ g_print ("Child is added: %s\n",
+ g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->new_value))));
+ }
+ }
+ else if (strcmp (values->property_name, "accessible-parent") == 0)
+ {
+ if (G_IS_VALUE (&values->old_value))
+ {
+ g_print ("Parent is removed: %s\n",
+ g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->old_value))));
+ }
+ if (G_IS_VALUE (&values->new_value))
+ {
+ g_print ("Parent is added: %s\n",
+ g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->new_value))));
+ }
+ }
+ else if (strcmp (values->property_name, "accessible-value") == 0)
+ {
+ if (G_VALUE_HOLDS_DOUBLE (&values->new_value))
+ {
+ g_print ("Value now is (double) %f\n",
+ g_value_get_double (&values->new_value));
+ }
+ }
+}
+
+static void
+_traverse_children (AtkObject *obj)
+{
+ gint n_children, i;
+ AtkRole role;
+
+ role = atk_object_get_role (obj);
+
+ if ((role == ATK_ROLE_TABLE) ||
+ (role == ATK_ROLE_TREE_TABLE))
+ return;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ _add_handler (child);
+ _traverse_children (child);
+ g_object_unref (G_OBJECT (child));
+ }
+}
+
+static void
+_add_handler (AtkObject *obj)
+{
+ static GPtrArray *obj_array = NULL;
+ gboolean found = FALSE;
+ gint i;
+
+ /*
+ * We create a property handler for each object if one was not associated
+ * with it already.
+ *
+ * We add it to our array of objects which have property handlers; if an
+ * object is destroyed it remains in the array.
+ */
+ if (obj_array == NULL)
+ obj_array = g_ptr_array_new ();
+
+ for (i = 0; i < obj_array->len; i++)
+ {
+ if (obj == g_ptr_array_index (obj_array, i))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ {
+ atk_object_connect_property_change_handler (obj,
+ (AtkPropertyChangeHandler*) _property_change_handler);
+ g_signal_connect (obj, "state-change",
+ (GCallback) _state_changed, NULL);
+ if (ATK_IS_SELECTION (obj))
+ g_signal_connect (obj, "selection_changed",
+ (GCallback) _selection_changed, NULL);
+ g_signal_connect (obj, "visible_data_changed",
+ (GCallback) _visible_data_changed, NULL);
+ if (ATK_IS_TABLE (obj))
+ g_signal_connect (obj, "model_changed",
+ (GCallback) _model_changed, NULL);
+ g_ptr_array_add (obj_array, obj);
+ }
+}
+
+static void
+_check_properties (AtkObject *obj)
+{
+ AtkRole role;
+
+ g_print ("Start of _check_properties: %s\n",
+ g_type_name (G_OBJECT_TYPE (obj)));
+
+ _add_handler (obj);
+
+ role = atk_object_get_role (obj);
+ if (role == ATK_ROLE_FRAME ||
+ role == ATK_ROLE_DIALOG)
+ {
+ /*
+ * Add handlers to all children.
+ */
+ _traverse_children (obj);
+ }
+ g_print ("End of _check_properties\n");
+}
+
+static void
+_create_event_watcher (void)
+{
+ id = atk_add_focus_tracker (_check_properties);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testprops Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <atk/atk.h>
+#include <gtk/gtk.h>
+
+/*
+ * This module tests the selection interface on menu items.
+ * To use this module run the test program testgtk and use the menus
+ * option.
+ */
+static void _do_selection (AtkObject *obj);
+static gint _finish_selection (gpointer data);
+static AtkObject* _find_object (AtkObject* obj, AtkRole role);
+static void _print_type (AtkObject *obj);
+
+static AtkObject*
+_find_object (AtkObject *obj,
+ AtkRole role)
+{
+ /*
+ * Find the first object which is a descendant of the specified object
+ * which matches the specified role.
+ *
+ * This function returns a reference to the AtkObject which should be
+ * removed when finished with the object.
+ */
+ gint i;
+ gint n_children;
+ AtkObject *child;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ if (atk_object_get_role (child) == role)
+ {
+ return child;
+ }
+ found_obj = _find_object (child, role);
+ g_object_unref (child);
+ if (found_obj)
+ {
+ return found_obj;
+ }
+ }
+ return NULL;
+}
+
+static void _print_type (AtkObject *obj)
+{
+ const gchar * typename = NULL;
+ const gchar * name = NULL;
+ AtkRole role;
+
+ if (GTK_IS_ACCESSIBLE (obj))
+ {
+ GtkWidget* widget = NULL;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
+ typename = g_type_name (G_OBJECT_TYPE (widget));
+ g_print ("Widget type name: %s\n", typename ? typename : "NULL");
+ }
+ typename = g_type_name (G_OBJECT_TYPE (obj));
+ g_print ("Accessible type name: %s\n", typename ? typename : "NULL");
+ name = atk_object_get_name (obj);
+ g_print("Accessible Name: %s\n", (name) ? name : "NULL");
+ role = atk_object_get_role(obj);
+ g_print ("Accessible Role: %d\n", role);
+}
+
+static void
+_do_selection (AtkObject *obj)
+{
+ gint i;
+ AtkObject *selected;
+ AtkRole role;
+ AtkObject *selection_obj;
+
+ role = atk_object_get_role (obj);
+
+ if ((role == ATK_ROLE_FRAME) &&
+ (strcmp (atk_object_get_name (obj), "menus") == 0))
+ {
+ selection_obj = _find_object (obj, ATK_ROLE_MENU_BAR);
+ if (selection_obj)
+ {
+ g_object_unref (selection_obj);
+ }
+ }
+ else if (role == ATK_ROLE_COMBO_BOX)
+ {
+ selection_obj = obj;
+ }
+ else
+ return;
+
+ g_print ("*** Start do_selection ***\n");
+
+
+ if (!selection_obj)
+ {
+ g_print ("no selection_obj\n");
+ return;
+ }
+
+ i = atk_selection_get_selection_count (ATK_SELECTION (selection_obj));
+ if (i != 0)
+ {
+ for (i = 0; i < atk_object_get_n_accessible_children (selection_obj); i++)
+ {
+ if (atk_selection_is_child_selected (ATK_SELECTION (selection_obj), i))
+ {
+ g_print ("%d child selected\n", i);
+ }
+ else
+ {
+ g_print ("%d child not selected\n", i);
+ }
+ }
+ }
+ /*
+ * Should not be able to select all items on a menu bar
+ */
+ atk_selection_select_all_selection (ATK_SELECTION (selection_obj));
+ i = atk_selection_get_selection_count (ATK_SELECTION (selection_obj));
+ if ( i != 0)
+ {
+ g_print ("Unexpected selection count: %d, expected 0\n", i);
+ return;
+ }
+ /*
+ * There should not be any items selected
+ */
+ selected = atk_selection_ref_selection (ATK_SELECTION (selection_obj), 0);
+ if ( selected != NULL)
+ {
+ g_print ("Unexpected selection: %d, expected 0\n", i);
+ }
+ atk_selection_add_selection (ATK_SELECTION (selection_obj), 1);
+ g_timeout_add (2000, _finish_selection, selection_obj);
+ g_print ("*** End _do_selection ***\n");
+}
+
+static gint _finish_selection (gpointer data)
+{
+ AtkObject *obj = ATK_OBJECT (data);
+ AtkObject *selected;
+ gint i;
+ gboolean is_selected;
+
+ g_print ("*** Start Finish selection ***\n");
+
+ /*
+ * If being run for for menus, at this point menu item foo should be
+ * selected which means that its submenu should be visible.
+ */
+ i = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ if (i != 1)
+ {
+ g_print ("Unexpected selection count: %d, expected 1\n", i);
+ return FALSE;
+ }
+ selected = atk_selection_ref_selection (ATK_SELECTION (obj), 0);
+ g_return_val_if_fail (selected != NULL, FALSE);
+ g_print ("*** Selected Item ***\n");
+ _print_type (selected);
+ g_object_unref (selected);
+ is_selected = atk_selection_is_child_selected (ATK_SELECTION (obj), 1);
+ g_return_val_if_fail (is_selected, FALSE);
+ is_selected = atk_selection_is_child_selected (ATK_SELECTION (obj), 0);
+ g_return_val_if_fail (!is_selected, FALSE);
+ selected = atk_selection_ref_selection (ATK_SELECTION (obj), 1);
+ g_return_val_if_fail (selected == NULL, FALSE);
+ atk_selection_remove_selection (ATK_SELECTION (obj), 0);
+ i = atk_selection_get_selection_count (ATK_SELECTION (obj));
+ g_return_val_if_fail (i == 0, FALSE);
+ selected = atk_selection_ref_selection (ATK_SELECTION (obj), 0);
+ g_return_val_if_fail (selected == NULL, FALSE);
+ g_print ("*** End Finish selection ***\n");
+ return FALSE;
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_do_selection);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testselection Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include <glib-object.h>
+#include <atk/atk.h>
+
+/*
+ * To use this test module, run the test program testgtk and click on
+ * statusbar
+ */
+
+static void _check_statusbar (AtkObject *obj);
+static AtkObject* _find_object (AtkObject* obj, AtkRole role);
+static void _notify_handler (GObject *obj, GParamSpec *pspec);
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+static AtkObject*
+_find_object (AtkObject *obj,
+ AtkRole role)
+{
+ /*
+ * Find the first object which is a descendant of the specified object
+ * which matches the specified role.
+ *
+ * This function returns a reference to the AtkObject which should be
+ * removed when finished with the object.
+ */
+ gint i;
+ gint n_children;
+ AtkObject *child;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject* found_obj;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ if (atk_object_get_role (child) == role)
+ {
+ return child;
+ }
+ found_obj = _find_object (child, role);
+ g_object_unref (child);
+ if (found_obj)
+ {
+ return found_obj;
+ }
+ }
+ return NULL;
+}
+
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ const gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
+ const gchar *name = atk_object_get_name (obj);
+
+ g_print ("_property_change_handler: Accessible Type: %s\n",
+ type_name ? type_name : "NULL");
+ g_print ("_property_change_handler: Accessible name: %s\n",
+ name ? name : "NULL");
+ g_print ("_property_change_handler: PropertyName: %s\n",
+ values->property_name ? values->property_name: "NULL");
+ if (G_VALUE_HOLDS_STRING (&values->new_value))
+ g_print ("_property_change_handler: PropertyValue: %s\n",
+ g_value_get_string (&values->new_value));
+}
+
+static void _check_statusbar (AtkObject *obj)
+{
+ AtkRole role;
+ AtkObject *statusbar, *label;
+
+ role = atk_object_get_role (obj);
+ if (role != ATK_ROLE_FRAME)
+ return;
+
+ statusbar = _find_object (obj, ATK_ROLE_STATUSBAR);
+ if (!statusbar)
+ return;
+ g_print ("_check_statusbar\n");
+ label = atk_object_ref_accessible_child (statusbar, 0);
+ g_return_if_fail (label == NULL);
+
+ /*
+ * We get notified of changes to the label
+ */
+ g_signal_connect_closure_by_id (statusbar,
+ g_signal_lookup ("notify",
+ G_OBJECT_TYPE (statusbar)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_handler),
+ NULL, NULL),
+ FALSE);
+ atk_object_connect_property_change_handler (statusbar,
+ (AtkPropertyChangeHandler*) _property_change_handler);
+
+}
+
+static void
+_notify_handler (GObject *obj, GParamSpec *pspec)
+{
+ AtkObject *atk_obj = ATK_OBJECT (obj);
+ const gchar *name;
+
+ g_print ("_notify_handler: property: %s\n", pspec->name);
+ if (strcmp (pspec->name, "accessible-name") == 0)
+ {
+ name = atk_object_get_name (atk_obj);
+ g_print ("_notify_handler: value: |%s|\n", name ? name : "<NULL>");
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_statusbar);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("teststatusbar Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
--- /dev/null
+#include <string.h>
+#include "testtextlib.h"
+
+#define NUM_ROWS_TO_LOOP 30
+
+typedef struct
+{
+ GtkWidget *tb_others;
+ GtkWidget *tb_ref_selection;
+ GtkWidget *tb_ref_at;
+ GtkWidget *tb_ref_accessible_child;
+ GtkWidget *child_entry;
+ GtkWidget *row_entry;
+ GtkWidget *col_entry;
+ GtkWidget *index_entry;
+}TestChoice;
+
+static void _check_table (AtkObject *in_obj);
+void table_runtest(AtkObject *);
+static void other_runtest(AtkObject *obj);
+static void ref_at_runtest(AtkObject *obj, gint row, gint col);
+static void ref_accessible_child_runtest(AtkObject *obj, gint childno);
+static void ref_selection_runtest (AtkObject *obj, gint index);
+static void _selection_tests(AtkObject *obj);
+static void _display_header_info(gchar *type,
+ AtkObject *header_obj, gint header_num);
+static void _process_child(AtkObject *child_obj);
+
+static void _notify_table_row_inserted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_column_inserted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_row_deleted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_column_deleted (GObject *obj,
+ gint start_offset, gint length);
+static void _notify_table_row_reordered (GObject *obj);
+static void _notify_table_column_reordered (GObject *obj);
+static void _notify_table_child_added (GObject *obj,
+ gint index, AtkObject *child);
+static void _notify_table_child_removed (GObject *obj,
+ gint index, AtkObject *child);
+static void _property_signal_connect (AtkObject *obj);
+static void _property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+static gboolean tested_set_headers = FALSE;
+static void test_choice_gui (AtkObject **obj);
+static void nogui_runtest (AtkObject *obj);
+static void nogui_ref_at_runtest (AtkObject *obj);
+static void nogui_process_child (AtkObject *obj);
+
+static TestChoice *tc;
+static gint g_visibleGUI = 0;
+static AtkTable *g_table = NULL;
+static AtkObject *current_obj = NULL;
+gboolean g_done = FALSE;
+gboolean g_properties = TRUE;
+
+/*
+ * destroy
+ *
+ * Destroy Callback
+ *
+ */
+static void destroy (GtkWidget *widget, gpointer data)
+{
+ gtk_main_quit();
+}
+
+static void choicecb (GtkWidget *widget, gpointer data)
+{
+ AtkObject **ptr_to_obj = (AtkObject **)data;
+ AtkObject *obj = *ptr_to_obj;
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tc->tb_others)))
+ {
+ other_runtest(obj);
+ }
+ else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tc->tb_ref_selection)))
+ {
+ const gchar *indexstr;
+ gint index;
+
+ indexstr = gtk_entry_get_text(GTK_ENTRY(tc->index_entry));
+ index = string_to_int((gchar *)indexstr);
+
+ ref_selection_runtest(obj, index);
+ }
+ else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tc->tb_ref_at)))
+ {
+ const gchar *rowstr, *colstr;
+ gint row, col;
+
+ rowstr = gtk_entry_get_text(GTK_ENTRY(tc->row_entry));
+ colstr = gtk_entry_get_text(GTK_ENTRY(tc->col_entry));
+ row = string_to_int((gchar *)rowstr);
+ col = string_to_int((gchar *)colstr);
+
+ ref_at_runtest(obj, row, col);
+ }
+ else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tc->tb_ref_accessible_child)))
+ {
+ const gchar *childstr;
+ gint childno;
+ childstr = gtk_entry_get_text(GTK_ENTRY(tc->child_entry));
+ childno = string_to_int((gchar *)childstr);
+
+ ref_accessible_child_runtest(obj, childno);
+ }
+}
+
+static void _check_table (AtkObject *in_obj)
+{
+ AtkObject *obj = NULL;
+ const char *no_properties;
+ const char *no_gui;
+
+ no_properties = g_getenv ("TEST_ACCESSIBLE_NO_PROPERTIES");
+ no_gui = g_getenv ("TEST_ACCESSIBLE_NO_GUI");
+
+ if (no_properties != NULL)
+ g_properties = FALSE;
+ if (no_gui != NULL)
+ g_visibleGUI = 1;
+
+ obj = find_object_by_type(in_obj, "GailTreeView");
+ if (obj != NULL)
+ g_print("Found GailTreeView table in child!\n");
+ else
+ {
+ obj = find_object_by_type(in_obj, "GailCList");
+ if (obj != NULL)
+ g_print("Found GailCList in child!\n");
+ else
+ {
+ g_print("No object found %s\n", g_type_name (G_OBJECT_TYPE (in_obj)));
+ return;
+ }
+ }
+
+ g_print ("In _check_table\n");
+
+ if (!already_accessed_atk_object(obj))
+ {
+ /* Set up signal handlers */
+
+ g_print ("Adding signal handler\n");
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_inserted", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_column_inserted),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_inserted", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_row_inserted),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_deleted", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_column_deleted),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_deleted", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_row_deleted),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("column_reordered", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_column_reordered),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("row_reordered", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_table_row_reordered),
+ NULL, NULL),
+ FALSE);
+ g_signal_connect_closure (obj, "children_changed::add",
+ g_cclosure_new (G_CALLBACK (_notify_table_child_added),
+ NULL, NULL),
+ FALSE);
+
+ g_signal_connect_closure (obj, "children_changed::remove",
+ g_cclosure_new (G_CALLBACK (_notify_table_child_removed),
+ NULL, NULL),
+ FALSE);
+
+ }
+ g_table = ATK_TABLE(obj);
+
+ atk_object_connect_property_change_handler (obj,
+ (AtkPropertyChangeHandler*) _property_change_handler);
+
+ current_obj = obj;
+ /*
+ * The use of ¤t_obj allows us to change the object being processed
+ * in the GUI.
+ */
+ if (g_visibleGUI != 1)
+ test_choice_gui(¤t_obj);
+ else if (no_gui != NULL)
+ nogui_runtest(obj);
+}
+
+static
+void other_runtest(AtkObject *obj)
+{
+ AtkObject *header_obj;
+ AtkObject *out_obj;
+ const gchar *out_string;
+ GString *out_desc;
+ gint n_cols, n_rows;
+ gint rows_to_loop = NUM_ROWS_TO_LOOP;
+ gint i, j;
+ out_desc = g_string_sized_new(256);
+
+ n_cols = atk_table_get_n_columns(ATK_TABLE(obj));
+ n_rows = atk_table_get_n_rows(ATK_TABLE(obj));
+
+ g_print ("Number of columns is %d\n", n_cols);
+ g_print ("Number of rows is %d\n", n_rows);
+
+ /* Loop NUM_ROWS_TO_LOOP rows if possible */
+ if (n_rows < NUM_ROWS_TO_LOOP)
+ rows_to_loop = n_rows;
+
+ g_print ("\n");
+
+ /* Caption */
+
+ out_obj = atk_table_get_caption(ATK_TABLE(obj));
+ if (out_obj != NULL)
+ {
+ out_string = atk_object_get_name (out_obj);
+ if (out_string)
+ g_print("Caption Name is <%s>\n", out_string);
+ else
+ g_print("Caption has no name\n");
+ }
+ else
+ g_print("No caption\n");
+
+ /* Column descriptions and headers */
+
+ g_print ("\n");
+ for (i=0; i < n_cols; i++)
+ {
+ /* check default */
+ out_string = atk_table_get_column_description(ATK_TABLE(obj), i);
+ if (out_string != NULL)
+ g_print("%d: Column description is <%s>\n", i, out_string);
+ else
+ g_print("%d: Column description is <NULL>\n", i);
+
+ /* check setting a new value */
+
+ g_string_printf(out_desc, "new column description %d", i);
+
+ if (out_string == NULL || strcmp (out_string, out_desc->str) != 0)
+ {
+ g_print("%d, Setting the column description to <%s>\n",
+ i, out_desc->str);
+ atk_table_set_column_description(ATK_TABLE(obj), i, out_desc->str);
+ out_string = atk_table_get_column_description(ATK_TABLE(obj), i);
+ if (out_string != NULL)
+ g_print("%d: Column description is <%s>\n", i, out_string);
+ else
+ g_print("%d: Column description is <NULL>\n", i);
+ }
+
+ /* Column header */
+ header_obj = atk_table_get_column_header(ATK_TABLE(obj), i);
+ _display_header_info("Column", header_obj, i);
+ }
+
+ /* Row description */
+
+ g_print ("\n");
+
+ for (i=0; i < rows_to_loop; i++)
+ {
+ out_string = atk_table_get_row_description(ATK_TABLE(obj), i);
+ if (out_string != NULL)
+ g_print("%d: Row description is <%s>\n", i, out_string);
+ else
+ g_print("%d: Row description is <NULL>\n", i);
+
+ g_string_printf(out_desc, "new row description %d", i);
+
+ if (out_string == NULL || strcmp (out_string, out_desc->str) != 0)
+ {
+ g_print("%d: Setting the row description to <%s>\n",
+ i, out_desc->str);
+ atk_table_set_row_description(ATK_TABLE(obj), i, out_desc->str);
+
+ out_string = atk_table_get_row_description(ATK_TABLE(obj), i);
+ if (out_string != NULL)
+ g_print("%d: Row description is <%s>\n", i, out_string);
+ else
+ g_print("%d: Row description is <NULL>\n", i);
+ }
+
+ header_obj = atk_table_get_row_header(ATK_TABLE(obj), i);
+ _display_header_info("Row", header_obj, i);
+
+ for (j=0; j <n_cols; j++)
+ {
+ gint index = atk_table_get_index_at(ATK_TABLE(obj), i, j);
+ gint row, column;
+
+ column = atk_table_get_column_at_index (ATK_TABLE (obj), index);
+ g_return_if_fail (column == j);
+
+ row = atk_table_get_row_at_index (ATK_TABLE (obj), index);
+ g_return_if_fail (row == i);
+
+ if(atk_selection_is_child_selected(ATK_SELECTION(obj), index))
+ g_print("atk_selection_is_child_selected,index = %d returns TRUE\n", index);
+ /* Generic cell tests */
+ /* Just test setting column headers once. */
+
+ if (!tested_set_headers)
+ {
+ tested_set_headers = TRUE;
+
+ /* Hardcode to 1,1 for now */
+ g_print(
+ "Testing set_column_header for column %d, to table\n",
+ (n_cols - 1));
+ atk_table_set_column_header(ATK_TABLE(obj), (n_cols - 1), obj);
+
+ g_print("Testing set_row_header for row %d, to table\n", n_rows);
+ atk_table_set_row_header(ATK_TABLE(obj), n_rows, obj);
+ }
+ }
+ }
+
+ /* row/column extents */
+
+ g_print("\n");
+ g_print("Row extents at 1,1 is %d\n",
+ atk_table_get_row_extent_at(ATK_TABLE(obj), 1, 1));
+ g_print("Column extents at 1,1 is %d\n",
+ atk_table_get_column_extent_at(ATK_TABLE(obj), 1, 1));
+}
+
+static
+void ref_accessible_child_runtest(AtkObject *obj, gint child)
+{
+ AtkObject *child_obj;
+ /* ref_child */
+ g_print ("Accessing child %d\n", child);
+ child_obj = atk_object_ref_accessible_child (obj, child);
+ _property_signal_connect(child_obj);
+ if (child_obj != NULL)
+ _process_child(child_obj);
+}
+
+static
+void ref_selection_runtest (AtkObject *obj, gint index)
+{
+ AtkObject *child_obj;
+
+ /* use atk_selection_ref_selection just once to check it works */
+ child_obj = atk_selection_ref_selection(ATK_SELECTION(obj), index);
+ if (child_obj)
+ {
+ g_print("child_obj gotten from atk_selection_ref_selection\n");
+ g_object_unref (child_obj);
+ }
+ else
+ g_print("NULL returned by atk_selection_ref_selection\n");
+
+ _selection_tests(obj);
+}
+
+static
+void ref_at_runtest(AtkObject *obj, gint row, gint col)
+{
+ AtkObject *child_obj;
+ /* ref_at */
+
+ g_print("Testing ref_at row %d column %d\n", row, col);
+
+ child_obj = atk_table_ref_at(ATK_TABLE(obj), row, col);
+ _property_signal_connect(child_obj);
+
+ g_print("Row is %d, col is %d\n", row, col);
+
+ _process_child(child_obj);
+ if (child_obj)
+ g_object_unref (child_obj);
+}
+
+/**
+ * process_child
+ **/
+static void
+_process_child(AtkObject *child_obj)
+{
+ if (child_obj != NULL)
+ {
+ if (ATK_IS_TEXT(child_obj))
+ {
+ add_handlers(child_obj);
+ setup_gui(child_obj, runtest);
+ }
+ else
+ {
+ g_print("Interface is not text!\n");
+ }
+/*
+ if (ATK_IS_ACTION(child_obj))
+ {
+ gint i, j;
+ gchar *action_name;
+ gchar *action_description;
+ gchar *action_keybinding;
+ AtkAction *action = ATK_ACTION(child_obj);
+
+ i = atk_action_get_n_actions (action);
+ g_print ("Supports AtkAction with %d actions.\n", i);
+ for (j = 0; j < i; j++)
+ {
+ g_print ("Action %d:\n", j);
+ action_name = atk_action_get_name (action, j);
+ if (action_name)
+ g_print (" Name = %s\n", action_name);
+ action_description = atk_action_get_description (action, j);
+ if (action_description)
+ g_print (" Description = %s\n", action_description);
+ action_keybinding = atk_action_get_keybinding (action, j);
+ if (action_keybinding)
+ g_print (" Keybinding = %s\n", action_keybinding);
+ action_description = "new description";
+ g_print (" Setting description to %s\n", action_description);
+ atk_action_set_description (action, j, action_description);
+ action_description = atk_action_get_description (action, j);
+ if (action_description)
+ g_print (" New description is now %s\n", action_description);
+ }
+ }
+*/
+ }
+ else
+ {
+ g_print("Child is NULL!\n");
+ }
+}
+
+/**
+ * Combined tests on AtkTable and AtkSelection on individual rows rather than
+ * all of them
+ **/
+static void
+_selection_tests(AtkObject *obj)
+{
+ gint n_rows = 0;
+ gint n_cols = 0;
+ gint selection_count = 0;
+ gint i = 0;
+ gint *selected = NULL;
+ AtkTable *table;
+
+ table = ATK_TABLE (obj);
+
+ n_rows = atk_table_get_selected_rows(table, &selected);
+ for (i = 0; i < n_rows; i++)
+ {
+ g_print("atk_table_get_selected_row returns : %d\n",
+ selected[i]);
+ if (!atk_table_is_row_selected (table, selected[i]))
+ g_print("atk_table_is_row_selected returns false for selected row %d\n",
+ selected[i]);
+ }
+ g_free (selected);
+
+ selected = NULL;
+ n_cols = atk_table_get_selected_columns(table, &selected);
+ for (i = 0; i < n_cols; i++)
+ g_print("atk_table_get_selected_columns returns : %d\n", selected[i]);
+ g_free (selected);
+
+ selection_count = atk_selection_get_selection_count(ATK_SELECTION(obj));
+ g_print("atk_selection_get_selection_count returns %d\n", selection_count);
+
+ if (atk_table_is_row_selected(table, 2))
+ {
+ g_print("atk_table_is_row_selected (table, 2) returns TRUE\n");
+ atk_selection_clear_selection (ATK_SELECTION (obj));
+ if (atk_table_add_row_selection(table, 4))
+ g_print("atk_table_add_row_selection: selected row 4\n");
+ if (!atk_table_is_row_selected (table, 4))
+ g_print("atk_table_is_row_selected returns false for row 2\n");
+ if (atk_table_is_row_selected (table, 2))
+ g_print("atk_table_is_row_selected gives false positive for row 2\n");
+ }
+
+ if (atk_table_is_row_selected(table, 3))
+ {
+ if (atk_table_remove_row_selection(table, 3))
+ g_print("atk_table_remove_row_selection unselected row 3\n");
+ }
+
+ if (atk_table_is_selected(table, 5, 4))
+ {
+ atk_selection_clear_selection(ATK_SELECTION(obj));
+ g_print("atk_selection_clear_selection: just cleared all selected\n");
+ }
+
+ if (atk_table_is_column_selected(table, 2))
+ {
+ g_print("atk_table_is_column_selected(obj, 2) returns TRUE\n");
+ if (atk_table_add_column_selection(table, 4))
+ g_print("atk_table_add_column_selection: selected column 4\n");
+ g_print("atk_table_is_column_selected(obj, 2) returns TRUE\n");
+ }
+
+ if (atk_table_is_column_selected(table, 3))
+ {
+ if (atk_table_remove_column_selection(table, 3))
+ g_print("atk_table_remove_column_selection: unselected column 3\n");
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_table);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("TestTable Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
+
+static void
+_notify_table_row_inserted (GObject *obj, gint start_offset, gint length)
+{
+ g_print ("SIGNAL - Row inserted at position %d, num of rows inserted %d!\n",
+ start_offset, length);
+}
+
+static void
+_notify_table_column_inserted (GObject *obj, gint start_offset, gint length)
+{
+ g_print ("SIGNAL - Column inserted at position %d, num of columns inserted %d!\n",
+ start_offset, length);
+}
+
+static void
+_notify_table_row_deleted (GObject *obj, gint start_offset, gint length)
+{
+ g_print ("SIGNAL - Row deleted at position %d, num of rows deleted %d!\n",
+ start_offset, length);
+}
+
+static void
+_notify_table_column_deleted (GObject *obj, gint start_offset, gint length)
+{
+ g_print ("SIGNAL - Column deleted at position %d, num of columns deleted %d!\n",
+ start_offset, length);
+}
+
+static void
+_notify_table_row_reordered (GObject *obj)
+{
+ g_print ("SIGNAL - Row reordered!\n");
+}
+
+static void
+_notify_table_column_reordered (GObject *obj)
+{
+ g_print ("SIGNAL - Column reordered!\n");
+}
+
+static void _notify_table_child_added (GObject *obj,
+ gint index, AtkObject *child)
+{
+ g_print ("SIGNAL - Child added - index %d\n", index);
+}
+
+static void _notify_table_child_removed (GObject *obj,
+ gint index, AtkObject *child)
+{
+ g_print ("SIGNAL - Child removed - index %d\n", index);
+}
+
+static void
+_display_header_info(gchar *type, AtkObject *header_obj, gint header_num)
+{
+ if (header_obj != NULL)
+ {
+ AtkRole role;
+ role = atk_object_get_role(header_obj);
+
+ if (role == ATK_ROLE_PUSH_BUTTON)
+ {
+ g_print ("%d: %s header is a push button!\n", header_num, type);
+ }
+ else if (role == ATK_ROLE_LABEL)
+ {
+ g_print ("%d: %s header is a label!\n", header_num, type);
+ }
+ else if (ATK_IS_TEXT(header_obj))
+ {
+ gchar *header_text;
+
+ header_text = atk_text_get_text (ATK_TEXT (header_obj), 0, 3);
+ if (header_text != NULL)
+ {
+ g_print("%d: %s header is a text value <%s>\n", header_num,
+ type, header_text);
+ }
+ else
+ {
+ g_print("%d: %s header is a text value <NULL>\n", header_num,
+ type);
+ }
+ }
+ else
+ {
+ g_print ("%d: %s header is of type %s!\n", header_num,
+ type, atk_role_get_name (role));
+ }
+ }
+ else
+ {
+ g_print ("%d: %s header object is NULL!\n", header_num, type);
+ }
+}
+
+static void _property_signal_connect (AtkObject *obj)
+{
+ if (g_properties && obj != NULL)
+ {
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("property_change", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_property_change_handler),
+ NULL, NULL),
+ FALSE);
+ }
+}
+
+static void
+_property_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ gchar *obj_text;
+ const gchar *name;
+
+ if (g_table != NULL)
+ {
+ gint index = atk_object_get_index_in_parent(obj);
+
+ if (index >= 0)
+ g_print("Index is %d, row is %d, col is %d\n", index,
+ atk_table_get_row_at_index(g_table, index),
+ atk_table_get_column_at_index(g_table, index));
+ else
+ g_print ("index: %d for %s\n", index, g_type_name (G_OBJECT_TYPE (obj)));
+ }
+
+ if (ATK_IS_TEXT(obj))
+ {
+ obj_text = atk_text_get_text (ATK_TEXT (obj), 0, 15);
+ if (obj_text == NULL)
+ g_print(" Cell text is <NULL>\n");
+ else
+ g_print(" Cell text is <%s>\n", obj_text);
+ }
+
+ g_print(" PropertyName <%s>\n",
+ values->property_name ? values->property_name: "NULL");
+ g_print(" - ");
+
+ if (&values->old_value != NULL && G_IS_VALUE (&values->old_value))
+ {
+ GType old_type = G_VALUE_TYPE (&values->old_value);
+
+ switch (old_type)
+ {
+ case G_TYPE_INT:
+ g_print("value was <%d>\n", g_value_get_int (&values->old_value));
+ break;
+ case G_TYPE_STRING:
+ name = g_value_get_string (&values->old_value);
+ if (name != NULL)
+ g_print ("value was <%s>\n", name);
+ else
+ g_print ("value was <NULL>\n");
+ break;
+ default:
+ g_print("value was <unknown type>\n");
+ break;
+ }
+ }
+ else
+ {
+ g_print("value was <not a value>\n");
+ }
+ g_print(" - ");
+ if (&values->new_value != NULL && G_IS_VALUE (&values->new_value))
+ {
+ GType new_type = G_VALUE_TYPE (&values->new_value);
+
+ switch (new_type)
+ {
+ case G_TYPE_INT:
+ g_print("value is <%d>\n", g_value_get_int (&values->new_value));
+ break;
+ case G_TYPE_STRING:
+ name = g_value_get_string (&values->new_value);
+ if (name != NULL)
+ g_print ("value is <%s>\n", name);
+ else
+ g_print ("value is <NULL>\n");
+ break;
+ default:
+ g_print("value is <unknown type>\n");
+ break;
+ }
+ }
+ else
+ {
+ g_print("value is <not a value>\n");
+ }
+}
+
+static
+void test_choice_gui(AtkObject **obj)
+{
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *child_label;
+ GtkWidget *row_label;
+ GtkWidget *col_label;
+ GtkWidget *index_label;
+ GtkWidget *hseparator;
+ GtkWidget *hbuttonbox;
+ GtkWidget *button;
+
+
+ tc = (TestChoice *) g_malloc (sizeof(TestChoice));
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(window), "Test to run");
+
+ g_signal_connect(window, "destroy",
+ G_CALLBACK (destroy), &window);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE);
+ gtk_box_set_spacing(GTK_BOX(vbox), 10);
+
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_set_spacing(GTK_BOX(hbox), 10);
+ tc->tb_ref_selection = gtk_toggle_button_new_with_label("ref_selection");
+ gtk_box_pack_start (GTK_BOX (hbox), tc->tb_ref_selection, TRUE, TRUE, 0);
+ index_label = gtk_label_new("index: ");
+ gtk_box_pack_start (GTK_BOX (hbox), index_label, TRUE, TRUE, 0);
+ tc->index_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(tc->index_entry), "1");
+ gtk_box_pack_start (GTK_BOX (hbox), tc->index_entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_set_spacing(GTK_BOX(hbox), 10);
+ tc->tb_ref_at = gtk_toggle_button_new_with_label("ref_at");
+ gtk_box_pack_start (GTK_BOX (hbox), tc->tb_ref_at, TRUE, TRUE, 0);
+ row_label = gtk_label_new("row:");
+ gtk_box_pack_start (GTK_BOX (hbox), row_label, TRUE, TRUE, 0);
+ tc->row_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(tc->row_entry), "1");
+ gtk_box_pack_start (GTK_BOX (hbox), tc->row_entry, TRUE, TRUE, 0);
+ col_label = gtk_label_new("column:");
+ gtk_box_pack_start (GTK_BOX (hbox), col_label, TRUE, TRUE, 0);
+ tc->col_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(tc->col_entry), "1");
+ gtk_box_pack_start (GTK_BOX (hbox), tc->col_entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_set_spacing(GTK_BOX(hbox), 10);
+ tc->tb_ref_accessible_child = gtk_toggle_button_new_with_label("ref_accessible_child");
+ gtk_box_pack_start (GTK_BOX (hbox), tc->tb_ref_accessible_child, TRUE, TRUE, 0);
+ child_label = gtk_label_new("Child no:");
+ gtk_box_pack_start (GTK_BOX (hbox), child_label, TRUE, TRUE, 0);
+ tc->child_entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(tc->child_entry), "1");
+ gtk_box_pack_start (GTK_BOX (hbox), tc->child_entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+
+ tc->tb_others = gtk_toggle_button_new_with_label("others");
+ gtk_box_pack_start (GTK_BOX (vbox), tc->tb_others, TRUE, TRUE, 0);
+
+ hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_box_pack_start (GTK_BOX (vbox), hseparator, TRUE, TRUE, 0);
+
+ button = gtk_button_new_with_mnemonic("_Run Test");
+
+ hbuttonbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox),
+ GTK_BUTTONBOX_SPREAD);
+ gtk_box_pack_end (GTK_BOX (hbuttonbox), GTK_WIDGET (button), TRUE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (vbox), hbuttonbox, TRUE, TRUE, 0);
+ g_signal_connect(button, "clicked", G_CALLBACK (choicecb), obj);
+
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+ gtk_widget_show(vbox);
+ gtk_widget_show(window);
+ gtk_widget_show_all(GTK_WIDGET(window));
+
+ g_visibleGUI = 1;
+}
+
+void static
+nogui_runtest (AtkObject *obj)
+{
+ g_print ("Running non-GUI tests...\n");
+ other_runtest (obj);
+ nogui_ref_at_runtest (obj);
+}
+
+static void
+nogui_ref_at_runtest (AtkObject *obj)
+{
+ AtkObject *child_obj;
+ gint i, j;
+ gint n_cols;
+ gint rows_to_loop = 5;
+
+ n_cols = atk_table_get_n_columns (ATK_TABLE(obj));
+
+ if (atk_table_get_n_rows(ATK_TABLE(obj)) < rows_to_loop)
+ rows_to_loop = atk_table_get_n_rows (ATK_TABLE(obj));
+
+ for (i=0; i < rows_to_loop; i++)
+ {
+ /* Just the first rows_to_loop rows */
+ for (j=0; j < n_cols; j++)
+ {
+ gint index = atk_table_get_index_at(ATK_TABLE(obj), i, j);
+ if(atk_selection_is_child_selected(ATK_SELECTION(obj), index))
+ g_print("atk_selection_is_child_selected,index = %d returns TRUE\n", index);
+
+ g_print("Testing ref_at row %d column %d\n", i, j);
+
+ if (i == 3 && j == 0)
+ {
+ g_print("child_obj gotten from atk_selection_ref_selection\n");
+
+ /* use atk_selection_ref_selection just once to check it works */
+ child_obj = atk_selection_ref_selection(ATK_SELECTION(obj), index );
+ }
+ else
+ {
+ child_obj = atk_table_ref_at(ATK_TABLE(obj), i, j);
+ }
+
+ _property_signal_connect(child_obj);
+
+ g_print("Index is %d, row is %d, col is %d\n", index,
+ atk_table_get_row_at_index(ATK_TABLE(obj), index),
+ atk_table_get_column_at_index(ATK_TABLE(obj), index));
+
+ nogui_process_child (child_obj);
+
+ /* Generic cell tests */
+ /* Just test setting column headers once. */
+
+ if (!tested_set_headers)
+ {
+ tested_set_headers = TRUE;
+
+ g_print("Testing set_column_header for column %d, to cell value %d,%d\n",
+ j, i, j);
+ atk_table_set_column_header(ATK_TABLE(obj), j, child_obj);
+
+ g_print("Testing set_row_header for row %d, to cell value %d,%d\n",
+ i, i, j);
+ atk_table_set_row_header(ATK_TABLE(obj), i, child_obj);
+ }
+ if (child_obj)
+ g_object_unref (child_obj);
+ }
+ }
+}
+
+static void
+nogui_process_child (AtkObject *obj)
+{
+ gchar default_val[5] = "NULL";
+
+ if (ATK_IS_TEXT(obj))
+ {
+ gchar *current_text;
+ current_text = atk_text_get_text (ATK_TEXT(obj), 0, -1);
+ g_print ("Child supports text interface.\nCurrent text is %s\n", current_text);
+ }
+
+ if (ATK_IS_ACTION(obj))
+ {
+ AtkAction *action = ATK_ACTION(obj);
+ gint n_actions, i;
+ const gchar *name, *description;
+
+ n_actions = atk_action_get_n_actions (action);
+ g_print ("Child supports %d actions.\n", n_actions);
+ for (i = 0; i < n_actions; i++)
+ {
+ name = atk_action_get_name (action, i);
+ description = atk_action_get_description (action, i);
+
+ if (name == NULL)
+ name = default_val;
+ if (description == NULL)
+ description = default_val;
+
+ g_print (" %d: name = <%s>\n", i, name);
+ g_print (" description = <%s>\n", description);
+ }
+ }
+}
+
--- /dev/null
+#include <atk/atk.h>
+#include "testtextlib.h"
+
+#define NUM_VALID_ROLES 6
+
+static void _create_event_watcher (void);
+static void _check_text (AtkObject *obj);
+void runtest(AtkObject *, gint);
+
+static guint id1 = 0;
+static guint win_count = 0;
+
+static void _check_text (AtkObject *in_obj)
+{
+ AtkObject *obj = NULL;
+ AtkRole role;
+ gchar* title;
+ AtkRole valid_roles[NUM_VALID_ROLES];
+
+ if (g_getenv("TEST_ACCESSIBLE_DELAY") != NULL)
+ {
+ int max_cnt = string_to_int(g_getenv("TEST_ACCESSIBLE_DELAY"));
+ win_count++;
+ if (win_count <= max_cnt)
+ return;
+ }
+
+ /* Set Up */
+
+ valid_roles[0] = ATK_ROLE_TEXT;
+ valid_roles[1] = ATK_ROLE_LABEL;
+ valid_roles[2] = ATK_ROLE_ACCEL_LABEL;
+ valid_roles[3] = ATK_ROLE_PASSWORD_TEXT;
+ valid_roles[4] = ATK_ROLE_TABLE_CELL;
+ valid_roles[5] = ATK_ROLE_PANEL;
+
+ /* The following if/else grabs the windows name, or sets title to NULL if none. */
+ if (in_obj->name)
+ {
+ title = in_obj->name;
+ }
+ else
+ {
+ GtkWidget *toplevel;
+ GtkWidget* widget;
+
+ widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (in_obj));
+ if (widget == NULL)
+ title = NULL;
+
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ title = (gchar *) gtk_window_get_title (GTK_WINDOW (toplevel));
+ else
+ title = NULL;
+ }
+ /* If no window name, do nothing */
+ if (title == NULL)
+ return;
+ /*
+ * If testtext test program, find obj just by role since only one child
+ * with no name
+ */
+ else if (g_ascii_strncasecmp(title, "testtext", 7) == 0)
+ {
+ obj = find_object_by_role(in_obj, valid_roles, NUM_VALID_ROLES);
+ }
+ /*
+ * Otherwise, get obj by name and role so you can specify exactly which
+ * obj to run tests on
+ */
+ else
+ {
+ const gchar *test_accessible_name = g_getenv ("TEST_ACCESSIBLE_NAME");
+
+ if (test_accessible_name != NULL)
+ {
+ obj = find_object_by_accessible_name_and_role(in_obj,
+ test_accessible_name, valid_roles, NUM_VALID_ROLES);
+ }
+ if (obj != NULL)
+ {
+ if (atk_object_get_role (obj) == ATK_ROLE_PANEL)
+ {
+ /* Get the child and check whether it is a label */
+
+ obj = atk_object_ref_accessible_child (obj, 0);
+ g_assert (atk_object_get_role (obj) == ATK_ROLE_LABEL);
+ g_object_unref (obj);
+ }
+ g_print("Found valid name and role in child!\n");
+ }
+ else
+ {
+ obj = find_object_by_role(in_obj, valid_roles, NUM_VALID_ROLES - 1);
+ if (obj != NULL)
+ g_print("Found valid role in child\n");
+ }
+ }
+ if (obj == NULL)
+ {
+ g_print("Object not found\n");
+ return;
+ }
+ role = atk_object_get_role(obj);
+
+ g_print("_check_text - Found role type %s!\n\n", atk_role_get_name (role));
+
+ add_handlers(obj);
+
+ if (!(isVisibleDialog()))
+ setup_gui(obj, runtest);
+ atk_remove_focus_tracker (id1);
+}
+
+static void
+_create_event_watcher (void)
+{
+ id1 = atk_add_focus_tracker (_check_text);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testtext Module loaded.\n");
+ _create_event_watcher();
+
+ return 0;
+}
+
+
--- /dev/null
+#include <string.h>
+#include <stdio.h>
+#include "testtextlib.h"
+
+static AtkAttributeSet *attrib = NULL;
+static char result_string[2][6] = {"FALSE", "TRUE"};
+
+/**
+ * setup_gui:
+ * @obj: An @AtkObject
+ * @test: The callback to be run when the "Run Tests" button
+ * in the GUI is clicked.
+ *
+ * Sets up the GUI windows.
+ *
+ * Returns: the window number, or -1 if failure.
+ **/
+gint setup_gui(AtkObject *obj, TLruntest test)
+{
+ gchar *paramnames[MAX_PARAMS];
+ gchar *defaults[MAX_PARAMS];
+ static OutputWindow *tow = NULL;
+ gint window;
+
+ if (tow)
+ window = create_windows(obj, test, &tow);
+ else
+ window = create_windows(obj, test, &tow);
+
+ if (window == -1)
+ return -1;
+
+ /* Get Text [at|after|before] Offset Tests */
+ paramnames[0] = "offset";
+ defaults[0] = "1";
+ add_test(window, "atk_text_get_text_after_offset", 1, paramnames, defaults);
+ add_test(window, "atk_text_get_text_before_offset", 1, paramnames, defaults);
+ add_test(window, "atk_text_get_text_at_offset",1 , paramnames, defaults);
+
+ /* Get Character Count Test */
+ add_test(window, "atk_text_get_character_count", 0, NULL, NULL);
+
+ /* Get Character At Offset Test */
+ paramnames[0] = "offset";
+ defaults[0] = "1";
+ add_test(window, "atk_text_get_character_at_offset", 1, paramnames, defaults);
+
+ /* Get Text Test */
+ paramnames[0] = "position 1";
+ paramnames[1] = "position 2";
+ defaults[0] = "0";
+ defaults[1] = "5";
+ add_test(window, "atk_text_get_text", 2, paramnames, defaults);
+
+ /* Caret Tests */
+ add_test(window, "atk_text_get_caret_offset", 0, NULL, NULL);
+
+ paramnames[0] = "offset";
+ defaults[0] = "1";
+ add_test(window, "atk_text_set_caret_offset", 1, paramnames, defaults);
+
+ /* Selection Tests */
+ add_test(window, "atk_text_get_n_selections", 0, NULL, NULL);
+
+ paramnames[0] = "selection no";
+ defaults[0] = "0";
+ add_test(window, "atk_text_get_selection", 1, paramnames, defaults);
+
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "3";
+ defaults[1] = "8";
+ add_test(window, "atk_text_add_selection", 2, paramnames, defaults);
+
+ paramnames[0] = "selection no";
+ paramnames[1] = "start";
+ paramnames[2] = "end";
+ defaults[0] = "0";
+ defaults[1] = "5";
+ defaults[2] = "7";
+ add_test(window, "atk_text_set_selection", 3, paramnames, defaults);
+
+ paramnames[0] = "selection no";
+ defaults[0] = "0";
+ add_test(window, "atk_text_remove_selection", 1, paramnames, defaults);
+
+ paramnames[0] = "offset";
+ defaults[0] = "36";
+ add_test(window, "atk_text_get_run_attributes", 1, paramnames, defaults);
+
+ add_test(window, "atk_text_get_default_attributes", 0, paramnames, defaults);
+
+ paramnames[0] = "offset";
+ paramnames[1] = "coord mode";
+ defaults[0] = "0";
+ defaults[1] = "ATK_XY_SCREEN";
+ add_test(window, "atk_text_get_character_extents", 2, paramnames, defaults);
+
+ paramnames[0] = "x";
+ paramnames[1] = "y";
+ paramnames[2] = "coord mode";
+ defaults[0] = "106";
+ defaults[1] = "208";
+ defaults[2] = "ATK_XY_SCREEN";
+ add_test(window, "atk_text_get_offset_at_point", 3, paramnames, defaults);
+
+ /* Editable Text Tests */
+ if (ATK_IS_EDITABLE_TEXT(obj))
+ {
+
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "20";
+ defaults[1] = "27";
+ add_test(window, "atk_editable_text_set_run_attributes", 2, paramnames, defaults);
+
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "3";
+ defaults[1] = "5";
+ add_test(window, "atk_editable_text_cut_text", 2, paramnames, defaults);
+
+ paramnames[0] = "position";
+ defaults[0] = "8";
+ add_test(window, "atk_editable_text_paste_text", 1, paramnames, defaults);
+
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "15";
+ defaults[1] = "20";
+ add_test(window, "atk_editable_text_delete_text", 2, paramnames, defaults);
+ paramnames[0] = "start";
+ paramnames[1] = "end";
+ defaults[0] = "5";
+ defaults[1] = "20";
+ add_test(window, "atk_editable_text_copy_text", 2, paramnames, defaults);
+
+ paramnames[0] = "insert text";
+ paramnames[1] = "position";
+ defaults[0] = "this is my insert";
+ defaults[1] = "15";
+ add_test(window, "atk_editable_text_insert_text", 2, paramnames, defaults);
+ }
+ return window;
+}
+
+/**
+ * add_handlers:
+ * @obj: An #AtkObject
+ *
+ * Sets up text signal handlers.
+ *
+ **/
+void add_handlers(AtkObject *obj)
+{
+ if (!already_accessed_atk_object(obj))
+ {
+ /* Set up signal handlers */
+
+ g_print ("Adding signal handler\n");
+ g_signal_connect_closure_by_id (obj,
+ g_signal_lookup ("text_caret_moved", G_OBJECT_TYPE (obj)),
+ 0,
+ g_cclosure_new (G_CALLBACK (_notify_caret_handler),
+ NULL, NULL),
+ FALSE);
+
+ g_signal_connect_closure (obj, "text_changed::insert",
+ g_cclosure_new (G_CALLBACK (_notify_text_insert_handler),
+ NULL, NULL),
+ FALSE);
+
+ g_signal_connect_closure (obj, "text_changed::delete",
+ g_cclosure_new (G_CALLBACK (_notify_text_delete_handler),
+ NULL, NULL),
+ FALSE);
+ }
+}
+
+/**
+ * notify_text_insert_handler:
+ * @obj: A #Gobject
+ * @start_offset: Start offset of insert
+ * @end_offset: End offset of insert.
+ *
+ * Text inserted singal handler
+ **/
+void
+_notify_text_insert_handler (GObject *obj, int start_offset, int end_offset)
+{
+ g_print ("SIGNAL - Text inserted at position %d, length %d!\n",
+ start_offset, end_offset);
+}
+
+/**
+ * notify_text_delete_handler:
+ * @obj: A #Gobject
+ * @start_offset: Start offset of delete
+ * @end_offset: End offset of delete.
+ *
+ * Text deleted singal handler
+ **/
+void
+_notify_text_delete_handler (GObject *obj, int start_offset, int end_offset)
+{
+ g_print ("SIGNAL - Text deleted at position %d, length %d!\n",
+ start_offset, end_offset);
+}
+
+/**
+ * notify_caret_handler:
+ * @obj: A #Gobject
+ * @position: Caret position
+ *
+ * Caret (cursor) moved signal handler.
+ **/
+void
+_notify_caret_handler (GObject *obj, int position)
+{
+ g_print ("SIGNAL - The caret moved to position %d!\n", position);
+}
+
+/**
+ * runtest:
+ * @obj: An #AtkObject
+ * @win_val: The window number
+ *
+ * The callback to run when the "Run Tests" button on the
+ * Test GUI is clicked.
+ **/
+void
+runtest(AtkObject *obj, gint win_val)
+{
+ gint i, size;
+ gunichar uni_char;
+ gchar output[MAX_LINE_SIZE];
+ gchar **testsOn;
+
+ testsOn = tests_set(win_val, &size);
+
+ for(i = 0; i < size; i++)
+ {
+ gint param_int1, param_int2, start, end, j, x, y, height, width;
+ gchar *param_string1, *param_string2, *param_string3, *text;
+ gboolean result;
+ gint index;
+
+ if (strcmp(testsOn[i], "atk_text_get_text_at_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_text_at_offset", "offset");
+ param_int1 = string_to_int(param_string1);
+
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_WORD_END);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_WORD_START);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_LINE_END);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_LINE_START);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_END);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_START);
+ _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_CHAR);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_text_after_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_text_after_offset", "offset");
+ param_int1 = string_to_int(param_string1);
+
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_WORD_END);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_WORD_START);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_LINE_END);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_LINE_START);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_END);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_START);
+ _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_CHAR);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_text_before_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_text_before_offset", "offset");
+ param_int1 = string_to_int(param_string1);
+
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_WORD_END);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_WORD_START);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_LINE_END);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_LINE_START);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_END);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_START);
+ _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_CHAR);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_character_count") == 0)
+ {
+ param_int1 = atk_text_get_character_count (ATK_TEXT (obj));
+ sprintf(output, "\nText character count: %d\n", param_int1);
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_character_at_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_character_at_offset",
+ "offset");
+ uni_char = atk_text_get_character_at_offset (ATK_TEXT(obj),
+ string_to_int(param_string1));
+ sprintf(output, "\nCharacter at offset %d: |%x|\n",
+ string_to_int(param_string1), uni_char);
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_text", "position 1");
+ param_string2 = get_arg_of_func(win_val, "atk_text_get_text", "position 2");
+ text = atk_text_get_text (ATK_TEXT (obj), string_to_int(param_string1),
+ string_to_int(param_string2));
+ sprintf(output, "\nText %d, %d: %s\n", string_to_int(param_string1),
+ string_to_int(param_string2), text);
+ g_free (text);
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_caret_offset") == 0)
+ {
+ param_int1 = atk_text_get_caret_offset (ATK_TEXT (obj));
+ if (param_int1 == -1)
+ sprintf(output, "\nCaret offset: |Not Supported|\n");
+ else
+ sprintf(output, "\nCaret offset: %d\n", param_int1);
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_set_caret_offset") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_set_caret_offset", "offset");
+ atk_text_set_caret_offset(ATK_TEXT(obj), string_to_int(param_string1));
+ sprintf(output, "\nPutting caret at offset: |%d|\n",
+ string_to_int(param_string1));
+ param_int1 = atk_text_get_caret_offset (ATK_TEXT (obj));
+
+ if (param_int1 == -1)
+ sprintf(output, "\nCaret offset: |Not Supported|\n");
+ else
+ sprintf(output, "\nCaret offset was set at: |%d|\n", param_int1);
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_n_selections") == 0)
+ {
+ param_int1 = atk_text_get_n_selections(ATK_TEXT(obj));
+ if (param_int1 == -1)
+ {
+ sprintf(output, "\nNo selected regions\n");
+ set_output_buffer(output);
+ }
+
+ for (j = 0; j < param_int1; j++)
+ {
+ sprintf(output, "\nNumber of selected text regions is: |%d|\n", j);
+ set_output_buffer(output);
+
+ text = atk_text_get_selection(ATK_TEXT(obj), j, &start, &end);
+ if (text != NULL)
+ {
+ sprintf(output, "\nSelected text for region %d is: |%s|\n", j, text);
+ set_output_buffer(output);
+ sprintf(output,
+ "\nStart selection bounds: %d\tEnd selection bounds: %d\n",
+ start, end);
+ }
+ else
+ {
+ sprintf(output, "\nNo selected region %d\n", j);
+ }
+
+ set_output_buffer(output);
+ }
+ }
+
+ if (strcmp(testsOn[i], "atk_text_add_selection") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_add_selection", "start");
+ param_string2 = get_arg_of_func(win_val, "atk_text_add_selection", "end");
+ result = atk_text_add_selection(ATK_TEXT(obj),
+ string_to_int(param_string1), string_to_int(param_string2));
+ sprintf(output, "\nSet selection bounds between %d, and %d: %s",
+ string_to_int(param_string1), string_to_int(param_string2),
+ result_string[result]);
+ set_output_buffer(output);
+
+ param_int1 = atk_text_get_n_selections(ATK_TEXT(obj));
+ for (j = 0; j < param_int1; j++)
+ {
+ sprintf(output, "\nNumber of selected text region is: %d\n", j);
+ set_output_buffer(output);
+ text = atk_text_get_selection(ATK_TEXT(obj), j, &start, &end);
+
+ if (text != NULL)
+ {
+ sprintf(output, "\nSelected text for region %d is: |%s|\n", j, text);
+ set_output_buffer(output);
+ sprintf(output,
+ "\nStart selection bounds: %d\tEnd selection bounds: %d\n",
+ start, end);
+ }
+ else
+ {
+ sprintf(output, "\nNo selected region %d\n", j);
+ }
+
+ set_output_buffer(output);
+ }
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_selection") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_selection", "selection no");
+ text = atk_text_get_selection(ATK_TEXT(obj),
+ string_to_int(param_string1), &start, &end);
+
+ if (text != NULL)
+ {
+ sprintf(output, "\nSelected text for region %d is: |%s|\n",
+ string_to_int(param_string1), text);
+ set_output_buffer(output);
+ sprintf(output,
+ "\nStart selection bounds: %d\t End selection bounds: %d\n",
+ start, end);
+ }
+ else
+ {
+ sprintf(output, "\nNo selected region %d\n", string_to_int(param_string1));
+ }
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_set_selection") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_set_selection", "selection no");
+ param_string2 = get_arg_of_func(win_val, "atk_text_set_selection", "start");
+ param_string3 = get_arg_of_func(win_val, "atk_text_set_selection", "end");
+ result = atk_text_set_selection(ATK_TEXT(obj), string_to_int(param_string1),
+ string_to_int(param_string2), string_to_int(param_string3));
+ sprintf(output, "Set selection %d's bounds between %d and %d: %s\n",
+ string_to_int(param_string1), string_to_int(param_string2),
+ string_to_int(param_string3), result_string[result]);
+ set_output_buffer(output);
+ text = atk_text_get_selection(ATK_TEXT(obj), string_to_int(param_string1),
+ &start, &end);
+
+ if (text != NULL)
+ {
+ sprintf(output, "Selected text for the reset region %d is: |%s|\n",
+ string_to_int(param_string1), text);
+ set_output_buffer(output);
+ sprintf(output,
+ "\nNew start selection bounds: %d\tNew end selection bounds: %d\n",
+ start, end);
+ }
+ else
+ {
+ sprintf(output, "\nNo selected region %d\n", string_to_int(param_string1));
+ }
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_remove_selection") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_text_remove_selection", "selection no");
+ result = atk_text_remove_selection(ATK_TEXT(obj), string_to_int(param_string1));
+ sprintf(output, "Remove selection for region %d: %s\n",
+ string_to_int(param_string1), result_string[result]);
+ set_output_buffer(output);
+ text = atk_text_get_selection(ATK_TEXT(obj),
+ string_to_int(param_string1), &start, &end);
+
+ if (text != NULL)
+ sprintf(output, "\nRemoved regions text should be empty instead of: %s", text);
+ else
+ sprintf(output, "\nRemoved regions text should be empty, this is: ||");
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_run_attributes") == 0)
+ {
+ gint test_int;
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_run_attributes", "offset");
+ test_int = string_to_int(param_string1);
+ attrib = atk_text_get_run_attributes(ATK_TEXT(obj), test_int, &start, &end);
+ sprintf(output, "get_run_attributes at offset %i:\nStart: %i, End: %i\n", test_int,
+ start, end);
+ set_output_buffer(output);
+ if (attrib != NULL) {
+ GSList *node;
+ index = 0;
+ node = attrib;
+ while (node != NULL)
+ {
+ AtkAttribute* att = node->data;
+
+ sprintf(output, "List index: %i, Name: %s, Value: %s\n", index,
+ att->name, att->value);
+ set_output_buffer(output);
+ node = node->next;
+ index++;
+ }
+ atk_attribute_set_free (attrib);
+ }
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_default_attributes") == 0)
+ {
+ attrib = atk_text_get_default_attributes(ATK_TEXT(obj));
+ sprintf(output, "get_default_attributes\n");
+ set_output_buffer(output);
+ if (attrib != NULL) {
+ GSList *node;
+ index = 0;
+ node = attrib;
+ while (node != NULL)
+ {
+ AtkAttribute* att = node->data;
+
+ sprintf(output, "List index: %i, Name: %s, Value: %s\n", index,
+ att->name, att->value);
+ set_output_buffer(output);
+ node = node->next;
+ index++;
+ }
+ atk_attribute_set_free (attrib);
+ }
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_character_extents") == 0)
+ {
+ gint test_int;
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_character_extents",
+ "offset");
+ param_string2 = get_arg_of_func(win_val, "atk_text_get_character_extents",
+ "coord mode");
+ test_int = string_to_int(param_string1);
+ if (strcmp(param_string2, "ATK_XY_SCREEN") == 0)
+ {
+ atk_text_get_character_extents(ATK_TEXT(obj), test_int, &x, &y, &width,
+ &height, ATK_XY_SCREEN);
+ sprintf(output,
+ "get_character_extents at offset %i, mode: SCREEN\nX: %i, Y: %i, width: %i, height: %i\n",
+ test_int, x, y, width, height);
+ }
+ else if (strcmp(param_string2, "ATK_XY_WINDOW") == 0)
+ {
+ atk_text_get_character_extents(ATK_TEXT(obj), test_int, &x, &y, &width,
+ &height, ATK_XY_WINDOW);
+ sprintf(output,
+ "get_character_extents at offset %i, mode: WIDGET_WINDOW\nX: %i, Y: %i, width: %i, height: %i\n",
+ test_int, x, y, width, height);
+ }
+ else
+ sprintf(output, "get_character_extents_at_offset: Invalid coord mode argument!");
+
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_text_get_offset_at_point") == 0)
+ {
+ gint test_int;
+ param_string1 = get_arg_of_func(win_val, "atk_text_get_offset_at_point", "x");
+ param_string2 = get_arg_of_func(win_val, "atk_text_get_offset_at_point", "y");
+ param_string3 = get_arg_of_func(win_val, "atk_text_get_offset_at_point", "coord mode");
+ param_int1 = string_to_int(param_string1);
+ param_int2 = string_to_int(param_string2);
+ if (strcmp(param_string3, "ATK_XY_SCREEN") == 0)
+ {
+ test_int = atk_text_get_offset_at_point(ATK_TEXT(obj), param_int1, param_int2,
+ ATK_XY_SCREEN);
+ if (test_int != -1)
+ sprintf(output, "get_offset_at_point %i,%i mode: SCREEN is %i\n", param_int1, param_int2, test_int);
+ else
+ sprintf(output, "Cannot get_offset_at_point\n");
+ }
+ else if (strcmp(param_string3, "ATK_XY_WINDOW") == 0)
+ {
+ test_int = atk_text_get_offset_at_point(ATK_TEXT(obj), param_int1, param_int2,
+ ATK_XY_WINDOW);
+ if (test_int != -1)
+ sprintf(output, "get_offset_at_point %i,%i mode: WIDGET_WINDOW is %i\n", param_int1, param_int2, test_int);
+ else
+ sprintf(output, "Cannot get_offset_at_point\n");
+ }
+ else
+ sprintf(output, "get_offset_at_point: Invalid coord mode argument!");
+
+ set_output_buffer(output);
+ }
+ if (ATK_IS_EDITABLE_TEXT(obj))
+ {
+ if (strcmp(testsOn[i], "atk_editable_text_set_run_attributes") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val,
+ "atk_editable_text_set_run_attributes", "start");
+ param_string2 = get_arg_of_func(win_val,
+ "atk_editable_text_set_run_attributes", "end");
+ result = atk_editable_text_set_run_attributes(ATK_EDITABLE_TEXT(obj),
+ attrib, string_to_int(param_string1), string_to_int(param_string2));
+ if (result)
+ sprintf(output, "\nSetting attributes in range %d to %d...OK\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ else
+ sprintf(output, "\nSetting attributes in range %d to %d...Failed\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_cut_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_cut_text", "start");
+ param_string2 = get_arg_of_func(win_val, "atk_editable_text_cut_text", "end");
+ atk_editable_text_cut_text(ATK_EDITABLE_TEXT(obj),
+ string_to_int(param_string1), string_to_int(param_string2));
+ sprintf(output, "\nCutting text %d to %d...\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_paste_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_paste_text",
+ "position");
+ atk_editable_text_paste_text(ATK_EDITABLE_TEXT(obj),
+ string_to_int(param_string1));
+ sprintf(output, "\nPasting text to %d\n", string_to_int(param_string1));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_delete_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_delete_text", "start");
+ param_string2 = get_arg_of_func(win_val, "atk_editable_text_delete_text", "end");
+ atk_editable_text_delete_text(ATK_EDITABLE_TEXT(obj),
+ string_to_int(param_string1), string_to_int(param_string2));
+ sprintf(output, "\nDeleting text %d to %d...\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_copy_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_copy_text", "start");
+ param_string2 = get_arg_of_func(win_val, "atk_editable_text_copy_text", "end");
+ atk_editable_text_copy_text(ATK_EDITABLE_TEXT(obj),
+ string_to_int(param_string1), string_to_int(param_string2));
+ sprintf(output, "\nCopying text %d to %d...\n",
+ string_to_int(param_string1), string_to_int(param_string2));
+ set_output_buffer(output);
+ }
+
+ if (strcmp(testsOn[i], "atk_editable_text_insert_text") == 0)
+ {
+ param_string1 = get_arg_of_func(win_val, "atk_editable_text_insert_text",
+ "insert text");
+ param_string2 = get_arg_of_func(win_val, "atk_editable_text_insert_text",
+ "position");
+ param_int2 = string_to_int(param_string2);
+ atk_editable_text_insert_text(ATK_EDITABLE_TEXT(obj),
+ param_string1, strlen(param_string1), ¶m_int2);
+ sprintf(output, "\nInserting text at %d...\n", param_int2);
+ set_output_buffer(output);
+ }
+ }
+ }
+}
+
+/**
+ * _run_offset_test:
+ * @obj: An #AtkObject
+ * @type: The type of test to run. Can be "at", "before", or "after".
+ * @offset: The offset into the text buffer.
+ * @boundary: The boundary type.
+ *
+ * Tests the following ATK_TEXT API functions:
+ * atk_text_get_text_at_offset
+ * atk_text_get_text_before_offseet
+ * atk_text_get_text_after_offset
+ **/
+void _run_offset_test(AtkObject * obj, char * type, gint offset,
+ AtkTextBoundary boundary)
+{
+ gchar output[MAX_LINE_SIZE];
+ gchar default_val[5] = "NULL";
+ gchar *text;
+ gint startOffset, endOffset;
+
+ if (strcmp(type, "at") == 0)
+ text = atk_text_get_text_at_offset (ATK_TEXT (obj),
+ offset, boundary, &startOffset, &endOffset);
+ else if (strcmp(type, "before") == 0)
+ text = atk_text_get_text_before_offset (ATK_TEXT (obj),
+ offset, boundary, &startOffset, &endOffset);
+ else if (strcmp(type, "after") == 0)
+ text = atk_text_get_text_after_offset (ATK_TEXT (obj),
+ offset, boundary, &startOffset, &endOffset);
+ else
+ text = NULL;
+
+ if (text == NULL)
+ text = g_strdup (default_val);
+
+ if (boundary == ATK_TEXT_BOUNDARY_CHAR)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_CHAR|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_WORD_START)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_WORD_START|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_WORD_END)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_WORD_END|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_SENTENCE_START)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_SENTENCE_START|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_SENTENCE_END)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_SENTENCE_END|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_LINE_START)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_LINE_START|\n",
+ type, text);
+ else if (boundary == ATK_TEXT_BOUNDARY_LINE_END)
+ sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_LINE_END|\n",
+ type, text);
+ else
+ sprintf(output, "\n|%s| Text |%s| Boundary |UNKNOWN|\n",
+ type, text);
+
+ g_free (text);
+ set_output_buffer(output);
+
+ sprintf(output, "Offset %d, startOffset %d, endOffset %d\n",
+ offset, startOffset, endOffset);
+ set_output_buffer(output);
+}
--- /dev/null
+#include <stdio.h>
+#include <gtk/gtk.h>
+#include <atk/atk.h>
+#include "testlib.h"
+
+void add_handlers (AtkObject *obj);
+gint setup_gui (AtkObject *obj, TLruntest test);
+void runtest(AtkObject *obj, gint win_num);
+void _run_offset_test(AtkObject *obj, char * type, gint param_int1, AtkTextBoundary boundary);
+void _notify_caret_handler (GObject *obj, int position);
+void _notify_text_insert_handler (GObject *obj,
+ int start_offset, int end_offset);
+void _notify_text_delete_handler (GObject *obj,
+ int start_offset, int end_offset);
+
--- /dev/null
+#include <atk/atk.h>
+#include <gtk/gtk.h>
+#include "testlib.h"
+
+static void _notify_toplevel_child_added (GObject *obj,
+ guint index, AtkObject *child, gpointer user_data);
+static void _notify_toplevel_child_removed (GObject *obj,
+ guint index, AtkObject *child, gpointer user_data);
+static gboolean _button_press_event_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values, const GValue *param_values, gpointer data);
+
+static guint id;
+static gboolean g_register_listener = FALSE;
+static guint g_signal_listener = 0;
+static gint g_press_count = 0;
+
+static void
+_check_toplevel (AtkObject *obj)
+{
+ AtkObject *root_obj;
+ const gchar *name_string, *version_string;
+ gint max_depth;
+
+ g_print ("Start of _check_toplevel\n");
+ root_obj = atk_get_root();
+
+ if (!already_accessed_atk_object(root_obj))
+ {
+ g_signal_connect_closure (root_obj, "children_changed::add",
+ g_cclosure_new (G_CALLBACK (_notify_toplevel_child_added),
+ NULL, NULL),
+ FALSE);
+
+ g_signal_connect_closure (root_obj, "children_changed::remove",
+ g_cclosure_new (G_CALLBACK (_notify_toplevel_child_removed),
+ NULL, NULL),
+ FALSE);
+ }
+
+ name_string = atk_get_toolkit_name();
+ version_string = atk_get_toolkit_version();
+ g_print ("Toolkit name <%s> version <%s>\n", name_string,
+ version_string);
+
+ if (g_getenv("TEST_ACCESSIBLE_DEPTH") != NULL)
+ max_depth = string_to_int(g_getenv("TEST_ACCESSIBLE_DEPTH"));
+ else
+ max_depth = 2;
+
+ display_children_to_depth(root_obj, max_depth, 0, 0);
+ g_print ("End of _check_toplevel\n");
+
+ if (!g_register_listener)
+ {
+ g_print("Adding global event listener on buttons\n");
+ g_register_listener = TRUE;
+ g_signal_listener = atk_add_global_event_listener(_button_press_event_watcher,
+ "Gtk:GtkButton:pressed");
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ id = atk_add_focus_tracker (_check_toplevel);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testtoplevel Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
+
+static void _notify_toplevel_child_added (GObject *obj,
+ guint child_index, AtkObject *child, gpointer user_data)
+{
+ g_print ("SIGNAL - Child added - index %d\n", child_index);
+}
+
+static void _notify_toplevel_child_removed (GObject *obj,
+ guint child_index, AtkObject *child, gpointer user_data)
+{
+ g_print ("SIGNAL - Child removed - index %d\n", child_index);
+}
+
+static gboolean
+_button_press_event_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ gchar * button_name = (gchar *) data;
+
+ object = g_value_get_object (param_values + 0);
+
+ if (ATK_IS_IMPLEMENTOR(object))
+ {
+ AtkObject * atk_obj =
+ atk_implementor_ref_accessible(ATK_IMPLEMENTOR(object));
+
+ g_print("Button <%s> pressed %d times!\n", button_name,
+ (g_press_count + 1));
+ g_print("Displaying children of Button pressed!\n");
+ display_children(atk_obj, 0, 0);
+
+ if (g_press_count >= 5)
+ {
+ g_print("Removing global event listener on buttons\n");
+ atk_remove_global_event_listener(g_signal_listener);
+ g_signal_listener = 0;
+ g_press_count = 0;
+ g_register_listener = FALSE;
+ }
+ else
+ {
+ g_press_count++;
+ }
+ }
+
+ return TRUE;
+}
+
--- /dev/null
+#include <stdlib.h>
+#include <testlib.h>
+
+/*
+ * This module is for use with the test program testtreeview
+ */
+static gboolean state_change_watch (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+
+static void _check_table (AtkObject *in_obj);
+static void _check_cell_actions (AtkObject *in_obj);
+
+static gint _find_expander_column (AtkTable *table);
+static void _check_expanders (AtkTable *table,
+ gint expander_column);
+static void _runtest (AtkObject *obj);
+static void _create_event_watcher (void);
+static void row_inserted (AtkObject *obj,
+ gint row,
+ gint count);
+static void row_deleted (AtkObject *obj,
+ gint row,
+ gint count);
+static AtkObject *table_obj = NULL;
+static gint expander_column = -1;
+static gboolean editing_cell = FALSE;
+
+static gboolean
+state_change_watch (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ gboolean state_set;
+ const gchar *state_name;
+ AtkStateType state_type;
+
+ object = g_value_get_object (param_values + 0);
+ g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
+
+ state_name = g_value_get_string (param_values + 1);
+ state_set = g_value_get_boolean (param_values + 2);
+
+ g_print ("Object type: %s state: %s set: %d\n",
+ g_type_name (G_OBJECT_TYPE (object)), state_name, state_set);
+ state_type = atk_state_type_for_name (state_name);
+ if (state_type == ATK_STATE_EXPANDED)
+ {
+ AtkObject *parent = atk_object_get_parent (ATK_OBJECT (object));
+
+ if (ATK_IS_TABLE (parent))
+ _check_expanders (ATK_TABLE (parent), expander_column);
+ }
+ return TRUE;
+}
+
+static void
+_check_table (AtkObject *in_obj)
+{
+ AtkObject *obj;
+ AtkRole role[2];
+ AtkRole obj_role;
+ static gboolean emission_hook_added = FALSE;
+
+ if (!emission_hook_added)
+ {
+ emission_hook_added = TRUE;
+ g_signal_add_emission_hook (
+ g_signal_lookup ("state-change", ATK_TYPE_OBJECT),
+ /*
+ * To specify an emission hook for a particular state, e.g.
+ * ATK_STATE_EXPANDED, instead of 0 use
+ * g_quark_from_string (atk_state_type_get_name (ATK_STATE_EXPANDED))
+ */
+ 0,
+ state_change_watch, NULL, (GDestroyNotify) NULL);
+ }
+
+ role[0] = ATK_ROLE_TABLE;
+ role[1] = ATK_ROLE_TREE_TABLE;
+
+ g_print ("focus event for: %s\n", g_type_name (G_OBJECT_TYPE (in_obj)));
+
+ _check_cell_actions (in_obj);
+
+ obj_role = atk_object_get_role (in_obj);
+ if (obj_role == ATK_ROLE_TABLE_CELL)
+ obj = atk_object_get_parent (in_obj);
+ else
+ obj = find_object_by_role (in_obj, role, 2);
+ if (obj == NULL)
+ return;
+
+ editing_cell = FALSE;
+
+ if (obj != table_obj)
+ {
+ table_obj = obj;
+ g_print("Found %s table\n", g_type_name (G_OBJECT_TYPE (obj)));
+ g_signal_connect (G_OBJECT (obj),
+ "row_inserted",
+ G_CALLBACK (row_inserted),
+ NULL);
+ g_signal_connect (G_OBJECT (obj),
+ "row_deleted",
+ G_CALLBACK (row_deleted),
+ NULL);
+ /*
+ * Find expander column
+ */
+ if (ATK_IS_TABLE (obj))
+ {
+ if (atk_object_get_role (obj) == ATK_ROLE_TREE_TABLE)
+ {
+ expander_column = _find_expander_column (ATK_TABLE (obj));
+ if (expander_column == -1)
+ {
+ g_warning ("Expander column not found\n");
+ return;
+ }
+ }
+ _runtest(obj);
+ }
+ else
+ g_warning ("Table does not support AtkTable interface\n");
+ }
+ else
+ {
+ /*
+ * We do not call these functions at the same time as we set the
+ * signals as the GtkTreeView may not be displayed yet.
+ */
+ gint x, y, width, height, first_x, last_x, last_y;
+ gint first_row, last_row, first_column, last_column;
+ gint index;
+ AtkObject *first_child, *last_child, *header;
+ AtkComponent *component = ATK_COMPONENT (obj);
+ AtkTable *table = ATK_TABLE (obj);
+
+ atk_component_get_extents (component,
+ &x, &y, &width, &height, ATK_XY_WINDOW);
+ g_print ("WINDOW: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ atk_component_get_extents (component,
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+ g_print ("SCREEN: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ last_x = x + width - 1;
+ last_y = y + height - 1;
+ first_x = x;
+ header = atk_table_get_column_header (table, 0);
+ if (header)
+ {
+ atk_component_get_extents (ATK_COMPONENT (header),
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+ g_print ("Got column header: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ y += height;
+ }
+ first_child = atk_component_ref_accessible_at_point (component,
+ first_x, y, ATK_XY_SCREEN);
+ atk_component_get_extents (ATK_COMPONENT (first_child),
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+ g_print ("first_child: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ index = atk_object_get_index_in_parent (ATK_OBJECT (first_child));
+ first_row = atk_table_get_row_at_index (table, index);
+ first_column = atk_table_get_column_at_index (table, index);
+ g_print ("first_row: %d first_column: %d index: %d\n",
+ first_row, first_column, index);
+ g_assert (index == atk_table_get_index_at (table, first_row, first_column));
+ last_child = atk_component_ref_accessible_at_point (component,
+ last_x, last_y, ATK_XY_SCREEN);
+ if (last_child == NULL)
+ {
+ /* The TreeView may be bigger than the data */
+ gint n_children;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ last_child = atk_object_ref_accessible_child (obj, n_children - 1);
+ }
+ atk_component_get_extents (ATK_COMPONENT (last_child),
+ &x, &y, &width, &height, ATK_XY_SCREEN);
+ g_print ("last_child: x: %d y: %d width: %d height: %d\n",
+ x, y, width, height);
+ index = atk_object_get_index_in_parent (ATK_OBJECT (last_child));
+ last_row = atk_table_get_row_at_index (table, index);
+ last_column = atk_table_get_column_at_index (table, index);
+ g_print ("last_row: %d last_column: %d index: %d\n",
+ last_row, last_column, index);
+ g_assert (index == atk_table_get_index_at (table, last_row, last_column));
+ g_object_unref (first_child);
+ g_object_unref (last_child);
+
+ if (expander_column >= 0)
+ {
+ gint n_rows, i;
+ gint x, y, width, height;
+
+ n_rows = atk_table_get_n_rows (table);
+ for (i = 0; i < n_rows; i++)
+ {
+ AtkObject *child_obj;
+ AtkStateSet *state_set;
+ gboolean showing;
+
+ child_obj = atk_table_ref_at (table, i, expander_column);
+ state_set = atk_object_ref_state_set (child_obj);
+ showing = atk_state_set_contains_state (state_set,
+ ATK_STATE_SHOWING);
+ g_object_unref (state_set);
+ atk_component_get_extents (ATK_COMPONENT (child_obj),
+ &x, &y, &width, &height,
+ ATK_XY_SCREEN);
+ g_object_unref (child_obj);
+ if (showing)
+ g_print ("Row: %d Column: %d x: %d y: %d width: %d height: %d\n",
+ i, expander_column, x, y, width, height);
+ }
+ }
+ }
+}
+
+static void
+_check_cell_actions (AtkObject *in_obj)
+{
+ AtkRole role;
+ AtkAction *action;
+ gint n_actions, i;
+
+ role = atk_object_get_role (in_obj);
+ if (role != ATK_ROLE_TABLE_CELL)
+ return;
+
+ if (!ATK_IS_ACTION (in_obj))
+ return;
+
+ if (editing_cell)
+ return;
+
+ action = ATK_ACTION (in_obj);
+
+ n_actions = atk_action_get_n_actions (action);
+
+ for (i = 0; i < n_actions; i++)
+ {
+ const gchar* name;
+
+ name = atk_action_get_name (action, i);
+ g_print ("Action %d is %s\n", i, name);
+#if 0
+ if (strcmp (name, "edit") == 0)
+ {
+ editing_cell = TRUE;
+ atk_action_do_action (action, i);
+ }
+#endif
+ }
+ return;
+}
+
+static gint
+_find_expander_column (AtkTable *table)
+{
+ gint n_columns, i;
+ gint retval = -1;
+
+ n_columns = atk_table_get_n_columns (table);
+ for (i = 0; i < n_columns; i++)
+ {
+ AtkObject *cell;
+ AtkRelationSet *relation_set;
+
+ cell = atk_table_ref_at (table, 0, i);
+ relation_set = atk_object_ref_relation_set (cell);
+ if (atk_relation_set_contains (relation_set,
+ ATK_RELATION_NODE_CHILD_OF))
+ retval = i;
+ g_object_unref (relation_set);
+ g_object_unref (cell);
+ if (retval >= 0)
+ break;
+ }
+ return retval;
+}
+
+static void
+_check_expanders (AtkTable *table,
+ gint expander_column)
+{
+ gint n_rows, i;
+
+ n_rows = atk_table_get_n_rows (table);
+
+ for (i = 0; i < n_rows; i++)
+ {
+ AtkObject *cell;
+ AtkRelationSet *relation_set;
+ AtkRelation *relation;
+ GPtrArray *target;
+ gint j;
+
+ cell = atk_table_ref_at (table, i, expander_column);
+
+ relation_set = atk_object_ref_relation_set (cell);
+ relation = atk_relation_set_get_relation_by_type (relation_set,
+ ATK_RELATION_NODE_CHILD_OF);
+ g_assert (relation);
+ target = atk_relation_get_target (relation);
+ g_assert (target->len == 1);
+ for (j = 0; j < target->len; j++)
+ {
+ AtkObject *target_obj;
+ AtkRole role;
+ gint target_index, target_row;
+
+ target_obj = g_ptr_array_index (target, j);
+ role = atk_object_get_role (target_obj);
+
+ switch (role)
+ {
+ case ATK_ROLE_TREE_TABLE:
+ g_print ("Row %d is top level\n", i);
+ break;
+ case ATK_ROLE_TABLE_CELL:
+ target_index = atk_object_get_index_in_parent (target_obj);
+ target_row = atk_table_get_row_at_index (table, target_index);
+ g_print ("Row %d has parent at %d\n", i, target_row);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ }
+ g_object_unref (relation_set);
+ g_object_unref (cell);
+ }
+}
+
+static void
+_create_event_watcher (void)
+{
+ atk_add_focus_tracker (_check_table);
+}
+
+int
+gtk_module_init (gint argc,
+ char *argv[])
+{
+ g_print ("testtreetable Module loaded\n");
+
+ _create_event_watcher ();
+
+ return 0;
+}
+
+static void
+_runtest (AtkObject *obj)
+{
+ AtkObject *child_obj;
+ AtkTable *table;
+ AtkObject *caption;
+ gint i;
+ gint n_cols, n_rows, n_children;
+
+ table = ATK_TABLE (obj);
+ n_children = atk_object_get_n_accessible_children (ATK_OBJECT (obj));
+ n_cols = atk_table_get_n_columns (table);
+ n_rows = atk_table_get_n_rows (table);
+ g_print ("n_children: %d n_rows: %d n_cols: %d\n",
+ n_children, n_rows, n_cols);
+
+ for (i = 0; i < n_rows; i++)
+ {
+ gint index = atk_table_get_index_at (table, i, expander_column);
+ gint index_in_parent;
+
+ child_obj = atk_table_ref_at (table, i, expander_column);
+ index_in_parent = atk_object_get_index_in_parent (child_obj);
+ g_print ("index: %d %d row %d column %d\n", index, index_in_parent, i, expander_column);
+
+ g_object_unref (child_obj);
+ }
+ caption = atk_table_get_caption (table);
+ if (caption)
+ {
+ const gchar *caption_name = atk_object_get_name (caption);
+
+ g_print ("Caption: %s\n", caption_name ? caption_name : "<null>");
+ }
+ for (i = 0; i < n_cols; i++)
+ {
+ AtkObject *header;
+
+ header = atk_table_get_column_header (table, i);
+ g_print ("Header for column %d is %p\n", i, header);
+ if (header)
+ {
+ const gchar *name;
+ AtkRole role;
+ AtkObject *parent;
+ AtkObject *child;
+ gint index;
+
+ name = atk_object_get_name (header);
+ role = atk_object_get_role (header);
+ parent = atk_object_get_parent (header);
+
+ if (parent)
+ {
+ index = atk_object_get_index_in_parent (header);
+ g_print ("Parent: %s index: %d\n", G_OBJECT_TYPE_NAME (parent), index);
+ child = atk_object_ref_accessible_child (parent, 0);
+ g_print ("Child: %s %p\n", G_OBJECT_TYPE_NAME (child), child);
+ if (index >= 0)
+ {
+ child = atk_object_ref_accessible_child (parent, index);
+ g_print ("Index: %d child: %s\n", index, G_OBJECT_TYPE_NAME (child));
+ g_object_unref (child);
+ }
+ }
+ else
+ g_print ("Parent of header is NULL\n");
+ g_print ("%s %s %s\n", G_OBJECT_TYPE_NAME (header), name ? name: "<null>", atk_role_get_name (role));
+ }
+ }
+}
+
+static void
+row_inserted (AtkObject *obj,
+ gint row,
+ gint count)
+{
+#if 0
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+#endif
+ gint index;
+
+ g_print ("row_inserted: row: %d count: %d\n", row, count);
+ index = atk_table_get_index_at (ATK_TABLE (obj), row+1, 0);
+ g_print ("index for first column of next row is %d\n", index);
+
+#if 0
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+ if (GTK_IS_TREE_STORE (tree_model))
+ {
+ GtkTreeStore *tree_store;
+ GtkTreePath *tree_path;
+ GtkTreeIter tree_iter;
+
+ tree_store = GTK_TREE_STORE (tree_model);
+ tree_path = gtk_tree_path_new_from_string ("3:0");
+ gtk_tree_model_get_iter (tree_model, &tree_iter, tree_path);
+ gtk_tree_path_free (tree_path);
+ gtk_tree_store_remove (tree_store, &tree_iter);
+ }
+#endif
+}
+
+static void
+row_deleted (AtkObject *obj,
+ gint row,
+ gint count)
+{
+#if 0
+ GtkWidget *widget;
+ GtkTreeView *tree_view;
+ GtkTreeModel *tree_model;
+#endif
+ gint index;
+
+ g_print ("row_deleted: row: %d count: %d\n", row, count);
+ index = atk_table_get_index_at (ATK_TABLE (obj), row+1, 0);
+ g_print ("index for first column of next row is %d\n", index);
+
+#if 0
+ widget = GTK_ACCESSIBLE (obj)->widget;
+ tree_view = GTK_TREE_VIEW (widget);
+ tree_model = gtk_tree_view_get_model (tree_view);
+ if (GTK_IS_TREE_STORE (tree_model))
+ {
+ GtkTreeStore *tree_store;
+ GtkTreePath *tree_path;
+ GtkTreeIter tree_iter, new_iter;
+
+ tree_store = GTK_TREE_STORE (tree_model);
+ tree_path = gtk_tree_path_new_from_string ("2");
+ gtk_tree_model_get_iter (tree_model, &tree_iter, tree_path);
+ gtk_tree_path_free (tree_path);
+ gtk_tree_store_insert_before (tree_store, &new_iter, NULL, &tree_iter);
+ }
+#endif
+}
--- /dev/null
+#include <string.h>
+#include <atk/atk.h>
+#include <gtk/gtk.h>
+
+static void _traverse_children (AtkObject *obj);
+static void _add_handler (AtkObject *obj);
+static void _check_values (AtkObject *obj);
+static void _value_change_handler (AtkObject *obj,
+ AtkPropertyValues *values);
+
+static guint id;
+
+static void _value_change_handler (AtkObject *obj,
+ AtkPropertyValues *values)
+{
+ const gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
+ GValue *value_back, val;
+
+ value_back = &val;
+
+ if (!ATK_IS_VALUE (obj)) {
+ return;
+ }
+
+ if (strcmp (values->property_name, "accessible-value") == 0) {
+ g_print ("_value_change_handler: Accessible Type: %s\n",
+ type_name ? type_name : "NULL");
+ if(G_VALUE_HOLDS_DOUBLE (&values->new_value))
+ {
+ g_print( "adjustment value changed : new value: %f\n",
+ g_value_get_double (&values->new_value));
+ }
+
+ g_print("Now calling the AtkValue interface functions\n");
+
+ atk_value_get_current_value (ATK_VALUE(obj), value_back);
+ g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
+ g_print ("atk_value_get_current_value returns %f\n",
+ g_value_get_double (value_back) );
+
+ atk_value_get_maximum_value (ATK_VALUE (obj), value_back);
+ g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
+ g_print ("atk_value_get_maximum returns %f\n",
+ g_value_get_double (value_back));
+
+ atk_value_get_minimum_value (ATK_VALUE (obj), value_back);
+ g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
+ g_print ("atk_value_get_minimum returns %f\n",
+ g_value_get_double (value_back));
+
+
+ }
+
+}
+
+static void _traverse_children (AtkObject *obj)
+{
+ gint n_children, i;
+
+ n_children = atk_object_get_n_accessible_children (obj);
+ for (i = 0; i < n_children; i++)
+ {
+ AtkObject *child;
+
+ child = atk_object_ref_accessible_child (obj, i);
+ _add_handler (child);
+ _traverse_children (child);
+ g_object_unref (G_OBJECT (child));
+ }
+}
+
+static void _add_handler (AtkObject *obj)
+{
+ static GPtrArray *obj_array = NULL;
+ gboolean found = FALSE;
+ gint i;
+
+ /*
+ * We create a property handler for each object if one was not associated
+ * with it already.
+ *
+ * We add it to our array of objects which have property handlers; if an
+ * object is destroyed it remains in the array.
+ */
+ if (obj_array == NULL)
+ obj_array = g_ptr_array_new ();
+
+ for (i = 0; i < obj_array->len; i++)
+ {
+ if (obj == g_ptr_array_index (obj_array, i))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ {
+ atk_object_connect_property_change_handler (obj,
+ (AtkPropertyChangeHandler*) _value_change_handler);
+ g_ptr_array_add (obj_array, obj);
+ }
+}
+
+static void _set_values (AtkObject *obj) {
+
+ GValue *value_back, val;
+ static gint count = 0;
+ gdouble double_value;
+
+ value_back = &val;
+
+ if(ATK_IS_VALUE(obj)) {
+ /* Spin button also inherits the text interfaces from GailEntry.
+ * Check when spin button recieves focus.
+ */
+
+ if(ATK_IS_TEXT(obj) && ATK_IS_EDITABLE_TEXT(obj)) {
+ if(count == 0) {
+ gint x;
+ gchar* text;
+ count++;
+ x = atk_text_get_character_count (ATK_TEXT (obj));
+ text = atk_text_get_text (ATK_TEXT (obj), 0, x);
+ g_print("Text : %s\n", text);
+ text = "5.7";
+ atk_editable_text_set_text_contents(ATK_EDITABLE_TEXT(obj),text);
+ g_print("Set text to %s\n",text);
+ atk_value_get_current_value(ATK_VALUE(obj), value_back);
+ g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
+ g_print("atk_value_get_current_value returns %f\n",
+ g_value_get_double( value_back));
+ }
+ } else {
+ memset (value_back, 0, sizeof (GValue));
+ g_value_init (value_back, G_TYPE_DOUBLE);
+ g_value_set_double (value_back, 10.0);
+ if (atk_value_set_current_value (ATK_VALUE (obj), value_back))
+ {
+ double_value = g_value_get_double (value_back);
+ g_print("atk_value_set_current_value returns %f\n",
+ double_value);
+ }
+ }
+ }
+}
+
+static void _check_values (AtkObject *obj)
+{
+ static gint calls = 0;
+ AtkRole role;
+
+ g_print ("Start of _check_values\n");
+
+ _set_values(obj);
+
+ _add_handler (obj);
+
+ if (++calls < 2)
+ {
+ /*
+ * Just do this on this on the first 2 objects visited
+ */
+ atk_object_set_name (obj, "test123");
+ atk_object_set_description (obj, "test123");
+ }
+
+ role = atk_object_get_role (obj);
+
+ if (role == ATK_ROLE_FRAME || role == ATK_ROLE_DIALOG)
+ {
+ /*
+ * Add handlers to all children.
+ */
+ _traverse_children (obj);
+ }
+ g_print ("End of _check_values\n");
+}
+
+static void
+_create_event_watcher (void)
+{
+ id = atk_add_focus_tracker (_check_values);
+}
+
+int
+gtk_module_init(gint argc, char* argv[])
+{
+ g_print("testvalues Module loaded\n");
+
+ _create_event_watcher();
+
+ return 0;
+}
include $(top_srcdir)/Makefile.decl
-SUBDIRS = input engines other
+SUBDIRS = input engines
if OS_UNIX
SUBDIRS += printbackends
+++ /dev/null
-include $(top_srcdir)/Makefile.decl
-
-SUBDIRS = gail
-
--include $(top_srcdir)/git.mk
+++ /dev/null
-=== ChangeLog discontinued ===
-
- With the move to git, GTK+ is switching from a ChangeLog file
- to relying on commit messages to provide change history. Please
- see README.commits for guidance on the expected message format.
-
-2009-03-25 Tor Lillqvist <tml@novell.com>
-
- Bug 575644 - Cygwin gail build patch
-
- * modules/other/gail/Makefile.am
- * modules/other/gail/libgail-util/Makefile.am
- * modules/other/gail/tests/Makefile.am: Use -no-undefined also on
- Cygwin. Patch from "Cygwin ports maintainer".
-
-2009-03-13 Matthias Clasen <mclasen@redhat.com>
-
- * === Released 2.16.0 ===
-
-2009-03-02 Matthias Clasen <mclasen@redhat.com>
-
- * === Released 2.15.5 ===
-
-2009-02-26 Li Yuan <li.yuan@sun.com>
-
- * Makefile.am:
- * gail.c: (gail_accessibility_module_init):
- * gail.h:
- * gailscalebutton.c: (gail_scale_button_class_init),
- (gail_scale_button_init), (gail_scale_button_initialize),
- (atk_action_interface_init), (gail_scale_button_do_action),
- (gail_scale_button_get_n_actions),
- (gail_scale_button_get_description),
- (gail_scale_button_action_get_name),
- (gail_scale_button_get_keybinding),
- (gail_scale_button_set_description), (atk_value_interface_init),
- (gail_scale_button_get_current_value),
- (gail_scale_button_get_maximum_value),
- (gail_scale_button_get_minimum_value),
- (gail_scale_button_get_minimum_increment),
- (gail_scale_button_set_current_value),
- (gail_scale_button_notify_gtk):
- * gailscalebutton.h:
- Bug #519090. Add accessibility support to GtkScaleButton.
- Support action and value interfaces. Patch from Jan Arne Petersen.
-
-2009-02-26 Li Yuan <li.yuan@sun.com>
-
- * gailbutton.c: (idle_do_action):
- Bug #561631. Patch from Yue Wang. Ref the button in the idle
- function to prevent the button being finalized.
-
-2009-02-25 Li Yuan <li.yuan@sun.com>
-
- * gailtreeview.c: (gail_tree_view_ref_accessible_at_point):
- Bug #325809. Get the cell from the coordinates based on
- bin_window.
-
-2009-02-25 Li Yuan <li.yuan@sun.com>
-
- * gailentry.c: (gail_entry_real_notify_gtk),
- (gail_entry_idle_notify_insert), (_gail_entry_insert_text_cb):
- Bug #520395. Notify the insert signal in the idle function. Let
- text_util has chance to update cache.
-
-2009-02-25 Li Yuan <li.yuan@sun.com>
-
- * gailtreeview.c: (is_cell_showing):
- Bug #571001. Set the cell's showing state based on bin_window
- coordinates.
-
-2009-02-17 Matthias Clasen <mclasen@redhat.com>
-
- * === Released 2.15.4 ===
-
-2009-02-17 Li Yuan <li.yuan@sun.com>
-
- * gailbutton.c: (idle_do_action):
- Bug #561631. Use g_queue_get_length to determine if a queue is empty.
-
-2009-02-04 Tor Lillqvist <tml@novell.com>
-
- Bug 570406 - gailutil.def is in srcdir, but used from builddir
-
- * libgail-util/Makefile.am: Use gailutil.def from srcdir. Drop
- useless rules to install/uninstall import libraries, libtool knows
- to install / uninstall them itself when installing / uninstalling
- a .la file. Add rules to install / uninstall the def file like for
- consistency, like with the other libraries in GTK+.
-
-2009-02-02 Matthias Clasen <mclasen@redhat.com>
-
- * === Released 2.15.3 ===
-
-2009-01-27 Matthias Clasen <mclasen@redhat.com>
-
- * === Released 2.15.2 ===
-
-2009-01-23 Matthias Clasen <mclasen@redhat.com>
-
- * === Released 2.15.1 ===
-
-2009-01-07 Brad Taylor <brad@getcoded.net>
-
- * gail.c:
- Bug #565110 – Add an env variable to disable Gail.
-
-2009-01-01 Matthias Clasen <mclasen@redhat.com>
-
- * === Released 2.15.0 ===
-
-2008-12-21 Tor Lillqvist <tml@novell.com>
-
- * gaillabel.c: #undef GTK_DISABLE_DEPRECATED here, too, to get
- GTK_IS_COMBO.
-
-2008-12-15 Li Yuan <li.yuan@sun.com>
-
- * gailitem.c:
- Bug #564555. #undef GTK_DISABLE_DEPRECATED where we need to access
- deprecated symbols.
-
-2008-12-12 Li Yuan <li.yuan@sun.com>
-
- * gailtreeview.c: Bug #512743.
- (gail_tree_view_changed_gtk): Clean cell before go through the info
- list, for "changed" signal could come before a "row-deleted".
- (clean_cell_info):
- Prevent the thread to be scheduled before clean_cell_info
- finish its job.
-
-2008-12-09 Michael Natterer <mitch@imendio.com>
-
- * Makefile.am
- * tests/Makefile.am: add GTK_DISABLE_DEPRECATED to CFLAGS.
-
- * gail.c
- * gailclist.c
- * gailclistcell.c
- * gailcombo.c
- * gaillist.c
- * gailmenu.c
- * gailoptionmenu.c
- * gailpixmap.c
- * gailprogressbar.c
- * gailtoplevel.c
- * gailwidget.c
- * gailwindow.c
- * tests/ferret.c
- * tests/testcombo.c
- * tests/testlib.h
- * tests/testoptionmenu.c: #undef it where we need to access
- deprecated cruft.
-
-2008-12-09 Michael Natterer <mitch@imendio.com>
-
- * gailtreeview.c: undeprecate.
-
-2008-11-27 Matthias Clasen <mclasen@redhat.com>
-
- Bug 353088 – gtk_expander_get_label should return the full label text
-
- * gailexpander.c: Don't rely on gtk_expander_get_label.
- Patch by Peter Johanson.
-
-2008-11-24 Li Yuan <li.yuan@sun.com>
-
- * gailnotebook.c: (gail_notebook_page_added):
- Bug #554002. Add cache's page count when add pages.
-
-2008-10-13 Matthias Clasen <mclasen@redhat.com>
-
- Bug 555953 – libferret missing link against libgtk-x11
-
- * test/Makefile.am: Link libferret against gtk.
-
-2008-10-07 Matthias Clasen <mclasen@redhat.com>
-
- Bug 554950 – gail must make itself resident
-
- * gail.c: Make the module resident, since it can't handle
- being unloaded.
-
-2008-09-22 Michael Natterer <mitch@imendio.com>
-
- * tests/ferret.c: s/GTK_SIGNAL_FUNC/G_CALLBACK/
-
-2008-09-20 Matthias Clasen <mclasen@redhat.com>
-
- * gailtextview.c:
- * gailbutton.c: Fix possible leaks of textutils.
-
-2008-09-19 Matthias Clasen <mclasen@redhat.com>
-
- * gailtreeview.c (garbage_collect_cell_data): Actually free
- the copied list.
-
-2008-08-21 Li Yuan <li.yuan@sun.com>
-
- * gailtreeview.c: (traverse_cells):
- Bug #548783. Change g_assert to g_return_if_fail to avoid
- unnucessary crash.
-
-2008-08-21 Li Yuan <li.yuan@sun.com>
-
- * gailtreeview.c: (model_row_deleted):
- Bug #548782. Emit children-changed::remove signal when a row is
- deleted in gtktreeview.
-
-2008-08-15 Michael Natterer <mitch@imendio.com>
-
- * gailbooleancell.c
- * gailimagecell.c
- * gailtextcell.c
- * gailwidget.c
- * tests/Makefile.am
- * tests/testbutton.c
- * tests/testimage.c
- * tests/testlib.c
- * tests/testmenuitem.c
- * tests/testnotebook.c
- * tests/testoptionmenu.c
- * tests/testpaned.c
- * tests/testselection.c
- * tests/testtable.c: some undeprecation.
-
- * libgail-util/Makefile.am. build with GDK_DISABLE_DEPRECATED
- and GTK_DISABLE_DEPRECATED.
-
-2008-08-11 Michael Natterer <mitch@imendio.com>
-
- * tests/ferret.c
- * tests/testlib.c
- * tests/testtable.c: don't use the deprecated
- gtk_box_pack_start_defaults()
-
-2008-08-04 Tor Lillqvist <tml@novell.com>
-
- * libgail-util/Makefile.am: Pass appropriate -machine flag to
- lib.exe.
-
-2008-07-02 Li Yuan <li.yuan@sun.com>
-
- * gailoptionmenu.c: (gail_option_menu_real_initialize),
- (gail_option_menu_changed):
- Bug #541167. Emit "object:property-change:accessible-name" when
- GailOptionMenui's name changes.
-
-2008-06-18 Michael Natterer <mitch@imendio.com>
-
- * gailimage.c (gail_image_get_image_size)
- * gailpixmap.c (gail_pixmap_get_image_size):
- s/gdk_window_get_size/gdk_drawable_get_size/
-
-2008-06-17 Michael Natterer <mitch@imendio.com>
-
- * gail.c
- * gailtoplevel.c: s/gtk_type_class/g_type_class_ref/
-
- * Makefile.am: add GDK_DISABLE_DEPRECATED to CPPFLAGS.
-
-2008-06-10 Li Yuan <li.yuan@sun.com>
-
- * gailtextview.c: (gail_text_view_set_caret_offset):
- Automatically scroll text caret to make it visible, when AT
- sets its offset.
-
-2008-06-06 Li Yuan <li.yuan@sun.com>
-
- * gail/gaillabel.c: (gail_label_real_notify_gtk):
- Before emitting "text_caret_moved", change the cursor to the
- changed bound. Bug #536927.
-
-2008-05-30 Michael Natterer <mitch@imendio.com>
-
- * gailcellparent.h
- * gailfactory.h
- * tests/testnotebook.c
- * tests/testtext.c
- * tests/testtoplevel.c
- * tests/testvalues.c: include <atk/atk.h> instead of individual
- files from ATK.
-
-2008-05-28 Michael Natterer <mitch@imendio.com>
-
- * gailwidget.h: include <gtk/gtk.h> instead of
- <gtk/gtkaccessible.h>
-
- * *.h: don't include anyting from gtk since all headers indirectly
- include gailwidget.h.
-
- * gailcellparent.c: include <gtk/gtk.h> instead of individual
- files.
-
- * gailcheckmenuitem.c
- * gailmenu.c
- * gailtreeview.c: remove all gtk includes since it's always
- included by including any gail header.
-
-2008-05-26 Michael Natterer <mitch@imendio.com>
-
- * libgail-util/gailmisc.h
- * libgail-util/gailtextutil.h: use G_BEGIN/END_DECLS.
-
-2008-05-24 Matthias Clasen <mclasen@redhat.com>
-
- Bug 504706 – wrong deallocator used for GError in gailtextview.c
-
- * gailtextview.c: Don't use g_free on a GError.
-
-2008-04-02 Li Yuan <li.yuan@.sun.com>
-
- * gailbutton.c: (idle_do_action):
- Patch from Alejandro Piñeiro Iglesias <apinheiro@igalia.com>.
- Bug #496167. Synthesize press and release GdkEvent in button's click
- action.
-
-2008-03-31 Li Yuan <li.yuan@sun.com>
-
- * gailbutton.c: (gail_button_ref_state_set):
- Bug #433324. add/remove selectable state depand on if the button can
- be focused.
-
-2008-03-20 Li Yuan <li.yuan@sun.com>
-
- * gailcell.c: (gail_cell_object_finalize):
- Bug #498079. Free cell's action info before free the action_list.
-
-2008-01-11 Li Yuan <li.yuan@sun.com>
-
- * gailtreeview.c: (gail_tree_view_real_initialize), (focus_in),
- (focus_out):
- Bug #508255. Remove ATK_STATE_FOCUSED state when focus jumps out.
- Emit "active-descendant-changed" and add ATK_STATE_FOCUSED state when
- focus comes in again.
-
-2008-01-11 Li Yuan <li.yuan@sun.com>
-
- * gailtreeview.c: (gail_tree_view_ref_child),
- (idle_cursor_changed):
- Bug #497218. Emit "active-descendant-changed" when focus first comes
- into treeview. Add/remove ATK_STATE_FOCUSED when cursor changes.
-
-2008-01-11 Li Yuan <li.yuan@sun.com>
-
- * gailtreeview.c: (gail_tree_view_get_n_rows):
- Bug #508715. Should use gtk_tree_path_free to free a GtkTreePath.
-
+++ /dev/null
-include $(top_srcdir)/Makefile.decl
-
-SUBDIRS = libgail-util tests
-
-if PLATFORM_WIN32
-no_undefined = -no-undefined
-endif
-
-moduledir = $(libdir)/gtk-3.0/modules
-module_LTLIBRARIES = libgail.la
-
-gail_c_sources = \
- gail-private-macros.h \
- gail.c \
- gailadjustment.c \
- gailarrow.c \
- gailbooleancell.c \
- gailbox.c \
- gailbutton.c \
- gailcalendar.c \
- gailcell.c \
- gailcellparent.c \
- gailcheckmenuitem.c \
- gailchecksubmenuitem.c \
- gailcombobox.c \
- gailcontainer.c \
- gailcontainercell.c \
- gailentry.c \
- gailexpander.c \
- gailframe.c \
- gailimage.c \
- gailimagecell.c \
- gaillabel.c \
- gaillinkbutton.c \
- gailmenu.c \
- gailmenushell.c \
- gailmenuitem.c \
- gailnotebook.c \
- gailnotebookpage.c \
- gailpaned.c \
- gailprogressbar.c \
- gailradiobutton.c \
- gailradiomenuitem.c \
- gailradiosubmenuitem.c \
- gailrange.c \
- gailrenderercell.c \
- gailscale.c \
- gailscalebutton.c \
- gailscrollbar.c \
- gailscrolledwindow.c \
- gailseparator.c \
- gailspinbutton.c \
- gailsubmenuitem.c \
- gailstatusbar.c \
- gailtextcell.c \
- gailtextview.c \
- gailtogglebutton.c \
- gailtoplevel.c \
- gailtreeview.c \
- gailutil.c \
- gailwidget.c \
- gailwindow.c
-
-libgailincludedir=$(includedir)/gail-3.0/gail
-
-gail_private_h_sources = \
- gail.h \
- gailadjustment.h \
- gailarrow.h \
- gailbooleancell.h \
- gailbox.h \
- gailbutton.h \
- gailcalendar.h \
- gailcell.h \
- gailcellparent.h \
- gailcheckmenuitem.h \
- gailchecksubmenuitem.h \
- gailcombobox.h \
- gailcontainercell.h \
- gailcontainer.h \
- gailentry.h \
- gailexpander.h \
- gailfactory.h \
- gailframe.h \
- gailimage.h \
- gailimagecell.h \
- gaillabel.h \
- gaillinkbutton.h \
- gailmenu.h \
- gailmenushell.h \
- gailmenuitem.h \
- gailnotebook.h \
- gailnotebookpage.h \
- gailpaned.h \
- gailprogressbar.h \
- gailradiobutton.h \
- gailradiomenuitem.h \
- gailradiosubmenuitem.h \
- gailrange.h \
- gailrenderercell.h \
- gailscale.h \
- gailscalebutton.h \
- gailscrollbar.h \
- gailscrolledwindow.h \
- gailseparator.h \
- gailspinbutton.h \
- gailsubmenuitem.h \
- gailstatusbar.h \
- gailtextcell.h \
- gailtextview.h \
- gailtogglebutton.h \
- gailtoplevel.h \
- gailtreeview.h \
- gailutil.h \
- gailwindow.h
-
-gail_public_h_sources = \
- gailwidget.h
-
-libgail_la_SOURCES = \
- $(gail_c_sources) \
- $(gail_public_h_sources) \
- $(gail_private_h_sources)
-
-libgailinclude_HEADERS = \
- $(gail_public_h_sources)
-
-libgail_la_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/gdk \
- -I$(top_builddir)/gdk \
- -I$(top_srcdir)/gtk \
- -I$(top_builddir)/gtk \
- -DGTK_VERSION=\"$(GTK_VERSION)\"\
- -DGDK_DISABLE_DEPRECATED \
- -DGTK_DISABLE_DEPRECATED \
- $(AM_CPPFLAGS)
-
-libgail_la_CFLAGS = \
- $(GTK_DEP_CFLAGS) \
- $(GTK_DEBUG_FLAGS) \
- $(AM_CFLAGS)
-
-libgail_la_LIBADD = \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/modules/other/gail/libgail-util/libgailutil-3.la \
- $(GTK_DEP_LIBS) \
- $(INTLLIBS)
-
-libgail_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version \
- $(no_undefined) \
- $(LDFLAGS)
-
--include $(top_srcdir)/git.mk
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#ifndef __GAIL_PRIVATE_MACROS_H__
-#define __GAIL_PRIVATE_MACROS_H__
-
-G_BEGIN_DECLS
-
-/* Note: these macros are logic macros, not intended to warn on failure. */
-
-#define gail_return_val_if_fail(a, b) if (!(a)) return (b)
-#define gail_return_if_fail(a) if (!(a)) return
-
-G_END_DECLS
-
-#endif /* __GAIL_PRIVATE_MACROS_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <gtk/gtkx.h>
-#include "gail.h"
-#include "gailfactory.h"
-
-#define GNOME_ACCESSIBILITY_ENV "GNOME_ACCESSIBILITY"
-#define NO_GAIL_ENV "NO_GAIL"
-
-static gboolean gail_focus_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-static gboolean gail_select_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-static gboolean gail_deselect_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-static gboolean gail_switch_page_watcher(GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-static AtkObject* gail_get_accessible_for_widget (GtkWidget *widget,
- gboolean *transient);
-static void gail_finish_select (GtkWidget *widget);
-static void gail_map_cb (GtkWidget *widget);
-static void gail_map_submenu_cb (GtkWidget *widget);
-static gint gail_focus_idle_handler (gpointer data);
-static void gail_focus_notify (GtkWidget *widget);
-static void gail_focus_notify_when_idle (GtkWidget *widget);
-
-static void gail_focus_tracker_init (void);
-static void gail_focus_object_destroyed (gpointer data);
-static void gail_focus_tracker (AtkObject *object);
-static void gail_set_focus_widget (GtkWidget *focus_widget,
- GtkWidget *widget);
-static void gail_set_focus_object (AtkObject *focus_obj,
- AtkObject *obj);
-
-GtkWidget* focus_widget = NULL;
-static GtkWidget* next_focus_widget = NULL;
-static gboolean was_deselect = FALSE;
-static GtkWidget* subsequent_focus_widget = NULL;
-static GtkWidget* focus_before_menu = NULL;
-static guint focus_notify_handler = 0;
-static guint focus_tracker_id = 0;
-static GQuark quark_focus_object = 0;
-
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WIDGET, GailWidget, gail_widget, GTK_TYPE_WIDGET)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_CONTAINER, GailContainer, gail_container, GTK_TYPE_CONTAINER)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_BUTTON, GailButton, gail_button, GTK_TYPE_BUTTON)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_LINK_BUTTON, GailLinkButton, gail_link_button, GTK_TYPE_LINK_BUTTON)
-GAIL_IMPLEMENT_FACTORY_WITH_FUNC (GAIL_TYPE_MENU_ITEM, GailMenuItem, gail_menu_item, gail_menu_item_new)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_TOGGLE_BUTTON, GailToggleButton, gail_toggle_button, GTK_TYPE_TOGGLE_BUTTON)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_IMAGE, GailImage, gail_image, GTK_TYPE_IMAGE)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_TEXT_VIEW, GailTextView, gail_text_view, GTK_TYPE_TEXT_VIEW)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_COMBO_BOX, GailComboBox, gail_combo_box, GTK_TYPE_COMBO_BOX)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_ENTRY, GailEntry, gail_entry, GTK_TYPE_ENTRY)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU_SHELL, GailMenuShell, gail_menu_shell, GTK_TYPE_MENU_SHELL)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU, GailMenu, gail_menu, GTK_TYPE_MENU)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WINDOW, GailWindow, gail_window, GTK_TYPE_BIN)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_RANGE, GailRange, gail_range, GTK_TYPE_RANGE)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCALE, GailScale, gail_scale, GTK_TYPE_SCALE)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCALE_BUTTON, GailScaleButton, gail_scale_button, GTK_TYPE_SCALE_BUTTON)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_LABEL, GailLabel, gail_label, GTK_TYPE_LABEL)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_STATUSBAR, GailStatusbar, gail_statusbar, GTK_TYPE_STATUSBAR)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_NOTEBOOK, GailNotebook, gail_notebook, GTK_TYPE_NOTEBOOK)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_CALENDAR, GailCalendar, gail_calendar, GTK_TYPE_CALENDAR)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_PROGRESS_BAR, GailProgressBar, gail_progress_bar, GTK_TYPE_PROGRESS_BAR)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SPIN_BUTTON, GailSpinButton, gail_spin_button, GTK_TYPE_SPIN_BUTTON)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_TREE_VIEW, GailTreeView, gail_tree_view, GTK_TYPE_TREE_VIEW)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_FRAME, GailFrame, gail_frame, GTK_TYPE_FRAME)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_RADIO_BUTTON, GailRadioButton, gail_radio_button, GTK_TYPE_RADIO_BUTTON)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_ARROW, GailArrow, gail_arrow, GTK_TYPE_ARROW)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SEPARATOR, GailSeparator, gail_separator, GTK_TYPE_SEPARATOR)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_BOX, GailBox, gail_box, GTK_TYPE_BOX)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCROLLED_WINDOW, GailScrolledWindow, gail_scrolled_window, GTK_TYPE_SCROLLED_WINDOW)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_PANED, GailPaned, gail_paned, GTK_TYPE_PANED)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCROLLBAR, GailScrollbar, gail_scrollbar, GTK_TYPE_SCROLLBAR)
-GAIL_IMPLEMENT_FACTORY_WITH_FUNC (GAIL_TYPE_CHECK_MENU_ITEM, GailCheckMenuItem, gail_check_menu_item, gail_check_menu_item_new)
-GAIL_IMPLEMENT_FACTORY_WITH_FUNC (GAIL_TYPE_RADIO_MENU_ITEM, GailRadioMenuItem, gail_radio_menu_item, gail_radio_menu_item_new)
-GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_EXPANDER, GailExpander, gail_expander, GTK_TYPE_EXPANDER)
-GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_RENDERER_CELL, GailRendererCell, gail_renderer_cell, GTK_TYPE_CELL_RENDERER, gail_renderer_cell_new)
-GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_BOOLEAN_CELL, GailBooleanCell, gail_boolean_cell, GTK_TYPE_CELL_RENDERER_TOGGLE, gail_boolean_cell_new)
-GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_IMAGE_CELL, GailImageCell, gail_image_cell, GTK_TYPE_CELL_RENDERER_PIXBUF, gail_image_cell_new)
-GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY (GAIL_TYPE_TEXT_CELL, GailTextCell, gail_text_cell, GTK_TYPE_CELL_RENDERER_TEXT, gail_text_cell_new)
-
-static AtkObject*
-gail_get_accessible_for_widget (GtkWidget *widget,
- gboolean *transient)
-{
- AtkObject *obj = NULL;
- GType gnome_canvas;
-
- gnome_canvas = g_type_from_name ("GnomeCanvas");
-
- *transient = FALSE;
- if (!widget)
- return NULL;
-
- if (GTK_IS_ENTRY (widget))
- ;
- else if (GTK_IS_NOTEBOOK (widget))
- {
- GtkNotebook *notebook;
- gint page_num = -1;
-
- notebook = GTK_NOTEBOOK (widget);
- page_num = gtk_notebook_get_current_page (notebook);
- if (page_num != -1)
- {
- obj = gtk_widget_get_accessible (widget);
- obj = atk_object_ref_accessible_child (obj, page_num);
- g_object_unref (obj);
- }
- }
- else if (G_TYPE_CHECK_INSTANCE_TYPE ((widget), gnome_canvas))
- {
- GObject *focused_item;
- GValue value = {0, };
-
- g_value_init (&value, G_TYPE_OBJECT);
- g_object_get_property (G_OBJECT (widget), "focused_item", &value);
- focused_item = g_value_get_object (&value);
-
- if (focused_item)
- {
- AtkObject *tmp;
-
- obj = atk_gobject_accessible_for_object (G_OBJECT (focused_item));
- tmp = g_object_get_qdata (G_OBJECT (obj), quark_focus_object);
- if (tmp != NULL)
- obj = tmp;
- }
- }
- else if (GTK_IS_TOGGLE_BUTTON (widget))
- {
- GtkWidget *other_widget = gtk_widget_get_parent (widget);
- if (GTK_IS_COMBO_BOX (other_widget))
- {
- gail_set_focus_widget (other_widget, widget);
- widget = other_widget;
- }
- }
- if (obj == NULL)
- {
- AtkObject *focus_object;
-
- obj = gtk_widget_get_accessible (widget);
- focus_object = g_object_get_qdata (G_OBJECT (obj), quark_focus_object);
- /*
- * We check whether the object for this focus_object has been deleted.
- * This can happen when navigating to an empty directory in nautilus.
- * See bug #141907.
- */
- if (ATK_IS_GOBJECT_ACCESSIBLE (focus_object))
- {
- if (!atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (focus_object)))
- focus_object = NULL;
- }
- if (focus_object)
- obj = focus_object;
- }
-
- return obj;
-}
-
-static gboolean
-gail_focus_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- GtkWidget *widget;
- GdkEvent *event;
-
- object = g_value_get_object (param_values + 0);
- g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
-
- event = g_value_get_boxed (param_values + 1);
- widget = GTK_WIDGET (object);
-
- if (event->type == GDK_FOCUS_CHANGE)
- {
- if (event->focus_change.in)
- {
- if (GTK_IS_WINDOW (widget))
- {
- GtkWidget *focus_widget;
- GtkWindow *window;
- GtkWindowType type;
-
- window = GTK_WINDOW (widget);
- focus_widget = gtk_window_get_focus (window);
- g_object_get (window, "type", &type, NULL);
-
- if (focus_widget)
- {
- /*
- * If we already have a potential focus widget set this
- * windows's focus widget to focus_before_menu so that
- * it will be reported when menu item is unset.
- */
- if (next_focus_widget)
- {
- if (GTK_IS_MENU_ITEM (next_focus_widget) &&
- !focus_before_menu)
- {
- void *vp_focus_before_menu = &focus_before_menu;
- focus_before_menu = focus_widget;
- g_object_add_weak_pointer (G_OBJECT (focus_before_menu), vp_focus_before_menu);
- }
-
- return TRUE;
- }
- widget = focus_widget;
- }
- else if (type == GTK_WINDOW_POPUP)
- {
- if (GTK_IS_BIN (widget))
- {
- GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
-
- if (GTK_IS_WIDGET (child) && gtk_widget_has_grab (child))
- {
- if (GTK_IS_MENU_SHELL (child))
- {
- if (gtk_menu_shell_get_selected_item (GTK_MENU_SHELL (child)))
- {
- /*
- * We have a menu which has a menu item selected
- * so we do not report focus on the menu.
- */
- return TRUE;
- }
- }
- widget = child;
- }
- }
- else /* popup window has no children; this edge case occurs in some custom code (OOo for instance) */
- {
- return TRUE;
- }
- }
- else /* Widget is a non-popup toplevel with no focus children;
- don't emit for this case either, as it's useless */
- {
- return TRUE;
- }
- }
- }
- else
- {
- if (next_focus_widget)
- {
- GtkWidget *toplevel;
-
- toplevel = gtk_widget_get_toplevel (next_focus_widget);
- if (toplevel == widget)
- next_focus_widget = NULL;
- }
- /* focus out */
- widget = NULL;
- }
- }
- else
- {
- if (event->type == GDK_MOTION_NOTIFY && gtk_widget_has_focus (widget))
- {
- if (widget == focus_widget)
- {
- return TRUE;
- }
- }
- else
- {
- return TRUE;
- }
- }
-
-#ifdef GDK_WINDOWING_X11
- /*
- * If the focus widget is a GtkSocket without a plug
- * then ignore the focus notification as the embedded
- * plug will report a focus notification.
- */
- if (GTK_IS_SOCKET (widget) &&
- gtk_socket_get_plug_window (GTK_SOCKET (widget)) != NULL)
- return TRUE;
-#endif
-
- /*
- * The widget may not yet be visible on the screen so we wait until it is.
- */
- gail_focus_notify_when_idle (widget);
- return TRUE;
-}
-
-static gboolean
-gail_select_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- GtkWidget *widget;
-
- object = g_value_get_object (param_values + 0);
- g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
-
- widget = GTK_WIDGET (object);
-
- if (!gtk_widget_get_mapped (widget))
- {
- g_signal_connect (widget, "map",
- G_CALLBACK (gail_map_cb),
- NULL);
- }
- else
- gail_finish_select (widget);
-
- return TRUE;
-}
-
-static void
-gail_finish_select (GtkWidget *widget)
-{
- if (GTK_IS_MENU_ITEM (widget))
- {
- GtkMenuItem* menu_item;
- GtkWidget *submenu;
-
- menu_item = GTK_MENU_ITEM (widget);
- submenu = gtk_menu_item_get_submenu (menu_item);
- if (submenu &&
- !gtk_widget_get_mapped (submenu))
- {
- /*
- * If the submenu is not visble, wait until it is before
- * reporting focus on the menu item.
- */
- gulong handler_id;
-
- handler_id = g_signal_handler_find (submenu,
- G_SIGNAL_MATCH_FUNC,
- g_signal_lookup ("map",
- GTK_TYPE_WINDOW),
- 0,
- NULL,
- (gpointer) gail_map_submenu_cb,
- NULL);
- if (!handler_id)
- g_signal_connect (submenu, "map",
- G_CALLBACK (gail_map_submenu_cb),
- NULL);
- return;
- }
- /*
- * If we are waiting to report focus on a menubar or a menu item
- * because of a previous deselect, cancel it.
- */
- if (was_deselect &&
- focus_notify_handler &&
- next_focus_widget &&
- (GTK_IS_MENU_BAR (next_focus_widget) ||
- GTK_IS_MENU_ITEM (next_focus_widget)))
- {
- void *vp_next_focus_widget = &next_focus_widget;
- g_source_remove (focus_notify_handler);
- g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
- next_focus_widget = NULL;
- focus_notify_handler = 0;
- was_deselect = FALSE;
- }
- }
- /*
- * If previously focused widget is not a GtkMenuItem or a GtkMenu,
- * keep track of it so we can return to it after menubar is deactivated
- */
- if (focus_widget &&
- !GTK_IS_MENU_ITEM (focus_widget) &&
- !GTK_IS_MENU (focus_widget))
- {
- void *vp_focus_before_menu = &focus_before_menu;
- focus_before_menu = focus_widget;
- g_object_add_weak_pointer (G_OBJECT (focus_before_menu), vp_focus_before_menu);
-
- }
- gail_focus_notify_when_idle (widget);
-
- return;
-}
-
-static void
-gail_map_cb (GtkWidget *widget)
-{
- gail_finish_select (widget);
-}
-
-static void
-gail_map_submenu_cb (GtkWidget *widget)
-{
- if (GTK_IS_MENU (widget))
- {
- GtkWidget *parent_menu_item;
-
- parent_menu_item = gtk_menu_get_attach_widget (GTK_MENU (widget));
- if (parent_menu_item)
- gail_finish_select (parent_menu_item);
- }
-}
-
-
-static gboolean
-gail_deselect_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- GtkWidget *widget;
- GtkWidget *menu_shell;
-
- object = g_value_get_object (param_values + 0);
- g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
-
- widget = GTK_WIDGET (object);
-
- if (!GTK_IS_MENU_ITEM (widget))
- return TRUE;
-
- if (subsequent_focus_widget == widget)
- subsequent_focus_widget = NULL;
-
- menu_shell = gtk_widget_get_parent (widget);
- if (GTK_IS_MENU_SHELL (menu_shell))
- {
- GtkWidget *parent_menu_shell;
-
- parent_menu_shell = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (menu_shell));
- if (parent_menu_shell)
- {
- GtkWidget *active_menu_item;
-
- active_menu_item = gtk_menu_shell_get_selected_item (GTK_MENU_SHELL (parent_menu_shell));
- if (active_menu_item)
- {
- gail_focus_notify_when_idle (active_menu_item);
- }
- }
- else
- {
- if (!GTK_IS_MENU_BAR (menu_shell))
- {
- gail_focus_notify_when_idle (menu_shell);
- }
- }
- }
- was_deselect = TRUE;
- return TRUE;
-}
-
-static gboolean
-gail_switch_page_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- GtkWidget *widget;
-
- object = g_value_get_object (param_values + 0);
- g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
-
- widget = GTK_WIDGET (object);
-
- if (!GTK_IS_NOTEBOOK (widget))
- return TRUE;
-
- if (gtk_notebook_get_current_page (GTK_NOTEBOOK (widget)) == -1)
- return TRUE;
-
- gail_focus_notify_when_idle (widget);
- return TRUE;
-}
-
-static gboolean
-gail_focus_idle_handler (gpointer data)
-{
- focus_notify_handler = 0;
- /*
- * The widget which was to receive focus may have been removed
- */
- if (!next_focus_widget)
- {
- if (next_focus_widget != data)
- return FALSE;
- }
- else
- {
- void *vp_next_focus_widget = &next_focus_widget;
- g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
- next_focus_widget = NULL;
- }
-
- gail_focus_notify (data);
-
- return FALSE;
-}
-
-static void
-gail_focus_notify (GtkWidget *widget)
-{
- AtkObject *atk_obj;
- gboolean transient;
-
- if (widget != focus_widget)
- {
- if (focus_widget)
- {
- void *vp_focus_widget = &focus_widget;
- g_object_remove_weak_pointer (G_OBJECT (focus_widget), vp_focus_widget);
- }
- focus_widget = widget;
- if (focus_widget)
- {
- void *vp_focus_widget = &focus_widget;
- g_object_add_weak_pointer (G_OBJECT (focus_widget), vp_focus_widget);
- /*
- * The UI may not have been updated yet; e.g. in gtkhtml2
- * html_view_layout() is called in a idle handler
- */
- if (focus_widget == focus_before_menu)
- {
- void *vp_focus_before_menu = &focus_before_menu;
- g_object_remove_weak_pointer (G_OBJECT (focus_before_menu), vp_focus_before_menu);
- focus_before_menu = NULL;
- }
- }
- gail_focus_notify_when_idle (focus_widget);
- }
- else
- {
- if (focus_widget)
- atk_obj = gail_get_accessible_for_widget (focus_widget, &transient);
- else
- atk_obj = NULL;
- /*
- * Do not report focus on redundant object
- */
- if (atk_obj &&
- (atk_object_get_role(atk_obj) != ATK_ROLE_REDUNDANT_OBJECT))
- atk_focus_tracker_notify (atk_obj);
- if (atk_obj && transient)
- g_object_unref (atk_obj);
- if (subsequent_focus_widget)
- {
- GtkWidget *tmp_widget = subsequent_focus_widget;
- subsequent_focus_widget = NULL;
- gail_focus_notify_when_idle (tmp_widget);
- }
- }
-}
-
-static void
-gail_focus_notify_when_idle (GtkWidget *widget)
-{
- if (focus_notify_handler)
- {
- if (widget)
- {
- /*
- * Ignore focus request when menu item is going to be focused.
- * See bug #124232.
- */
- if (GTK_IS_MENU_ITEM (next_focus_widget) && !GTK_IS_MENU_ITEM (widget))
- return;
-
- if (next_focus_widget)
- {
- if (GTK_IS_MENU_ITEM (next_focus_widget) && GTK_IS_MENU_ITEM (widget))
- {
- if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (next_focus_widget)) == gtk_widget_get_parent (widget))
- {
- if (subsequent_focus_widget)
- g_assert_not_reached ();
- subsequent_focus_widget = widget;
- return;
- }
- }
- }
- g_source_remove (focus_notify_handler);
- if (next_focus_widget)
- {
- void *vp_next_focus_widget = &next_focus_widget;
- g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
- next_focus_widget = NULL;
- }
- }
- else
- /*
- * Ignore if focus is being set to NULL and we are waiting to set focus
- */
- return;
- }
-
- if (widget)
- {
- void *vp_next_focus_widget = &next_focus_widget;
- next_focus_widget = widget;
- g_object_add_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
- }
- else
- {
- /*
- * We are about to report focus as NULL so remove the weak pointer
- * for the widget we were waiting to report focus on.
- */
- if (next_focus_widget)
- {
- void *vp_next_focus_widget = &next_focus_widget;
- g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
- next_focus_widget = NULL;
- }
- }
-
- focus_notify_handler = gdk_threads_add_idle (gail_focus_idle_handler, widget);
-}
-
-static gboolean
-gail_deactivate_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- GtkWidget *widget;
- GtkMenuShell *shell;
- GtkWidget *focus = NULL;
-
- object = g_value_get_object (param_values + 0);
- g_return_val_if_fail (GTK_IS_WIDGET(object), FALSE);
- widget = GTK_WIDGET (object);
-
- g_return_val_if_fail (GTK_IS_MENU_SHELL(widget), TRUE);
- shell = GTK_MENU_SHELL(widget);
- if (! gtk_menu_shell_get_parent_shell (shell))
- focus = focus_before_menu;
-
- /*
- * If we are waiting to report focus on a menubar or a menu item
- * because of a previous deselect, cancel it.
- */
- if (was_deselect &&
- focus_notify_handler &&
- next_focus_widget &&
- (GTK_IS_MENU_BAR (next_focus_widget) ||
- GTK_IS_MENU_ITEM (next_focus_widget)))
- {
- void *vp_next_focus_widget = &next_focus_widget;
- g_source_remove (focus_notify_handler);
- g_object_remove_weak_pointer (G_OBJECT (next_focus_widget), vp_next_focus_widget);
- next_focus_widget = NULL;
- focus_notify_handler = 0;
- was_deselect = FALSE;
- }
- gail_focus_notify_when_idle (focus);
-
- return TRUE;
-}
-
-static void
-gail_focus_tracker_init (void)
-{
- static gboolean emission_hooks_added = FALSE;
-
- if (!emission_hooks_added)
- {
- /*
- * We cannot be sure that the classes exist so we make sure that they do.
- */
- g_type_class_ref (GTK_TYPE_WIDGET);
- g_type_class_ref (GTK_TYPE_MENU_ITEM);
- g_type_class_ref (GTK_TYPE_MENU_SHELL);
- g_type_class_ref (GTK_TYPE_NOTEBOOK);
-
- /*
- * We listen for event_after signal and then check that the
- * event was a focus in event so we get called after the event.
- */
- g_signal_add_emission_hook (
- g_signal_lookup ("event-after", GTK_TYPE_WIDGET), 0,
- gail_focus_watcher, NULL, (GDestroyNotify) NULL);
- /*
- * A "select" signal is emitted when arrow key is used to
- * move to a list item in the popup window of a GtkCombo or
- * a menu item in a menu.
- */
- g_signal_add_emission_hook (
- g_signal_lookup ("select", GTK_TYPE_MENU_ITEM), 0,
- gail_select_watcher, NULL, (GDestroyNotify) NULL);
-
- /*
- * A "deselect" signal is emitted when arrow key is used to
- * move from a menu item in a menu to the parent menu.
- */
- g_signal_add_emission_hook (
- g_signal_lookup ("deselect", GTK_TYPE_MENU_ITEM), 0,
- gail_deselect_watcher, NULL, (GDestroyNotify) NULL);
-
- /*
- * We listen for deactivate signals on menushells to determine
- * when the "focus" has left the menus.
- */
- g_signal_add_emission_hook (
- g_signal_lookup ("deactivate", GTK_TYPE_MENU_SHELL), 0,
- gail_deactivate_watcher, NULL, (GDestroyNotify) NULL);
-
- /*
- * We listen for "switch-page" signal on a GtkNotebook to notify
- * when page has changed because of clicking on a notebook tab.
- */
- g_signal_add_emission_hook (
- g_signal_lookup ("switch-page", GTK_TYPE_NOTEBOOK), 0,
- gail_switch_page_watcher, NULL, (GDestroyNotify) NULL);
- emission_hooks_added = TRUE;
- }
-}
-
-static void
-gail_focus_object_destroyed (gpointer data)
-{
- GObject *obj;
-
- obj = G_OBJECT (data);
- g_object_set_qdata (obj, quark_focus_object, NULL);
- g_object_unref (obj);
-}
-
-static void
-gail_focus_tracker (AtkObject *focus_object)
-{
- /*
- * Do not report focus on redundant object
- */
- if (focus_object &&
- (atk_object_get_role(focus_object) != ATK_ROLE_REDUNDANT_OBJECT))
- {
- AtkObject *old_focus_object;
-
- if (!GTK_IS_ACCESSIBLE (focus_object))
- {
- AtkObject *parent;
-
- parent = focus_object;
- while (1)
- {
- parent = atk_object_get_parent (parent);
- if (parent == NULL)
- break;
- if (GTK_IS_ACCESSIBLE (parent))
- break;
- }
-
- if (parent)
- {
- gail_set_focus_object (focus_object, parent);
- }
- }
- else
- {
- old_focus_object = g_object_get_qdata (G_OBJECT (focus_object), quark_focus_object);
- if (old_focus_object)
- {
- g_object_weak_unref (G_OBJECT (old_focus_object),
- (GWeakNotify) gail_focus_object_destroyed,
- focus_object);
- g_object_set_qdata (G_OBJECT (focus_object), quark_focus_object, NULL);
- g_object_unref (G_OBJECT (focus_object));
- }
- }
- }
-}
-
-static void
-gail_set_focus_widget (GtkWidget *focus_widget,
- GtkWidget *widget)
-{
- AtkObject *focus_obj;
- AtkObject *obj;
-
- focus_obj = gtk_widget_get_accessible (focus_widget);
- obj = gtk_widget_get_accessible (widget);
- gail_set_focus_object (focus_obj, obj);
-}
-
-static void
-gail_set_focus_object (AtkObject *focus_obj,
- AtkObject *obj)
-{
- AtkObject *old_focus_obj;
-
- old_focus_obj = g_object_get_qdata (G_OBJECT (obj), quark_focus_object);
- if (old_focus_obj != obj)
- {
- if (old_focus_obj)
- g_object_weak_unref (G_OBJECT (old_focus_obj),
- (GWeakNotify) gail_focus_object_destroyed,
- obj);
- else
- /*
- * We call g_object_ref as if obj is destroyed
- * while the weak reference exists then destroying the
- * focus_obj would cause gail_focus_object_destroyed to be
- * called when obj is not a valid GObject.
- */
- g_object_ref (obj);
-
- g_object_weak_ref (G_OBJECT (focus_obj),
- (GWeakNotify) gail_focus_object_destroyed,
- obj);
- g_object_set_qdata (G_OBJECT (obj), quark_focus_object, focus_obj);
- }
-}
-
-/*
- * These exported symbols are hooked by gnome-program
- * to provide automatic module initialization and shutdown.
- */
-extern void gnome_accessibility_module_init (void);
-extern void gnome_accessibility_module_shutdown (void);
-
-static int gail_initialized = FALSE;
-
-static void
-gail_accessibility_module_init (void)
-{
- const char *env_a_t_support;
- gboolean a_t_support = FALSE;
-
- if (gail_initialized)
- {
- return;
- }
- gail_initialized = TRUE;
- quark_focus_object = g_quark_from_static_string ("gail-focus-object");
-
- env_a_t_support = g_getenv (GNOME_ACCESSIBILITY_ENV);
-
- if (env_a_t_support)
- a_t_support = atoi (env_a_t_support);
- if (a_t_support)
- fprintf (stderr, "GTK Accessibility Module initialized\n");
-
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WIDGET, gail_widget);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CONTAINER, gail_container);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_BUTTON, gail_button);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_LINK_BUTTON, gail_link_button);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU_ITEM, gail_menu_item);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_TOGGLE_BUTTON, gail_toggle_button);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_IMAGE, gail_image);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_TEXT_VIEW, gail_text_view);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_COMBO_BOX, gail_combo_box);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_ENTRY, gail_entry);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU_BAR, gail_menu_shell);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU, gail_menu);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WINDOW, gail_window);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_RANGE, gail_range);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCALE, gail_scale);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCALE_BUTTON, gail_scale_button);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_LABEL, gail_label);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_STATUSBAR, gail_statusbar);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_NOTEBOOK, gail_notebook);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CALENDAR, gail_calendar);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_PROGRESS_BAR, gail_progress_bar);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SPIN_BUTTON, gail_spin_button);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_TREE_VIEW, gail_tree_view);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_FRAME, gail_frame);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_TEXT, gail_text_cell);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_TOGGLE, gail_boolean_cell);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_PIXBUF, gail_image_cell);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER, gail_renderer_cell);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_RADIO_BUTTON, gail_radio_button);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_ARROW, gail_arrow);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SEPARATOR, gail_separator);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_BOX, gail_box);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCROLLED_WINDOW, gail_scrolled_window);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_PANED, gail_paned);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCROLLBAR, gail_scrollbar);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CHECK_MENU_ITEM, gail_check_menu_item);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_RADIO_MENU_ITEM, gail_radio_menu_item);
- GAIL_WIDGET_SET_FACTORY (GTK_TYPE_EXPANDER, gail_expander);
-
- atk_focus_tracker_init (gail_focus_tracker_init);
- focus_tracker_id = atk_add_focus_tracker (gail_focus_tracker);
-
- /* Initialize the GailUtility class */
- g_type_class_unref (g_type_class_ref (GAIL_TYPE_UTIL));
- g_type_class_unref (g_type_class_ref (GAIL_TYPE_MISC));
-}
-
-/**
- * gnome_accessibility_module_init:
- * @void:
- *
- * This method is invoked by name from libgnome's
- * gnome-program.c to activate accessibility support.
- **/
-void
-gnome_accessibility_module_init (void)
-{
- gail_accessibility_module_init ();
-}
-
-/**
- * gnome_accessibility_module_shutdown:
- * @void:
- *
- * This method is invoked by name from libgnome's
- * gnome-program.c to de-activate accessibility support.
- **/
-void
-gnome_accessibility_module_shutdown (void)
-{
- if (!gail_initialized)
- {
- return;
- }
- gail_initialized = FALSE;
- atk_remove_focus_tracker (focus_tracker_id);
-
- fprintf (stderr, "GTK Accessibility Module shutdown\n");
-
- /* FIXME: de-register the factory types so we can unload ? */
-}
-
-int
-gtk_module_init (gint *argc, char** argv[])
-{
- const char* env_no_gail;
- gboolean no_gail = FALSE;
-
- env_no_gail = g_getenv (NO_GAIL_ENV);
- if (env_no_gail)
- no_gail = atoi (env_no_gail);
-
- if (no_gail)
- return 0;
-
- gail_accessibility_module_init ();
-
- return 0;
-}
-
-const char *
-g_module_check_init (GModule *module)
-{
- g_module_make_resident (module);
-
- return NULL;
-}
-
+++ /dev/null
-#include "gailadjustment.h"
-#include "gailarrow.h"
-#include "gailbooleancell.h"
-#include "gailbox.h"
-#include "gailbutton.h"
-#include "gailcalendar.h"
-#include "gailcell.h"
-#include "gailcheckmenuitem.h"
-#include "gailcombobox.h"
-#include "gailcontainer.h"
-#include "gailcontainercell.h"
-#include "gailentry.h"
-#include "gailexpander.h"
-#include "gailframe.h"
-#include "gailimage.h"
-#include "gailimagecell.h"
-#include "gaillabel.h"
-#include "gaillinkbutton.h"
-#include "gailmenu.h"
-#include "gailmenushell.h"
-#include "gailmenuitem.h"
-#include "gailnotebook.h"
-#include "gailpaned.h"
-#include "gailprogressbar.h"
-#include "gailradiobutton.h"
-#include "gailradiomenuitem.h"
-#include "gailrenderercell.h"
-#include "gailrange.h"
-#include "gailscale.h"
-#include "gailscalebutton.h"
-#include "gailscrollbar.h"
-#include "gailscrolledwindow.h"
-#include "gailseparator.h"
-#include "gailspinbutton.h"
-#include "gailstatusbar.h"
-#include "gailtextcell.h"
-#include "gailtextview.h"
-#include "gailtogglebutton.h"
-#include "gailtoplevel.h"
-#include "gailtreeview.h"
-#include "gailutil.h"
-#include "gailwidget.h"
-#include "gailwindow.h"
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailadjustment.h"
-
-static void gail_adjustment_class_init (GailAdjustmentClass *klass);
-
-static void gail_adjustment_init (GailAdjustment *adjustment);
-
-static void gail_adjustment_real_initialize (AtkObject *obj,
- gpointer data);
-
-static void atk_value_interface_init (AtkValueIface *iface);
-
-static void gail_adjustment_get_current_value (AtkValue *obj,
- GValue *value);
-static void gail_adjustment_get_maximum_value (AtkValue *obj,
- GValue *value);
-static void gail_adjustment_get_minimum_value (AtkValue *obj,
- GValue *value);
-static void gail_adjustment_get_minimum_increment (AtkValue *obj,
- GValue *value);
-static gboolean gail_adjustment_set_current_value (AtkValue *obj,
- const GValue *value);
-
-G_DEFINE_TYPE_WITH_CODE (GailAdjustment, gail_adjustment, ATK_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
-
-static void
-gail_adjustment_class_init (GailAdjustmentClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->initialize = gail_adjustment_real_initialize;
-}
-
-static void
-gail_adjustment_init (GailAdjustment *adjustment)
-{
-}
-
-AtkObject*
-gail_adjustment_new (GtkAdjustment *adjustment)
-{
- GObject *object;
- AtkObject *atk_object;
-
- g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), NULL);
-
- object = g_object_new (GAIL_TYPE_ADJUSTMENT, NULL);
-
- atk_object = ATK_OBJECT (object);
- atk_object_initialize (atk_object, adjustment);
-
- return atk_object;
-}
-
-static void
-gail_adjustment_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkAdjustment *adjustment;
- GailAdjustment *gail_adjustment;
-
- ATK_OBJECT_CLASS (gail_adjustment_parent_class)->initialize (obj, data);
-
- adjustment = GTK_ADJUSTMENT (data);
-
- obj->role = ATK_ROLE_UNKNOWN;
- gail_adjustment = GAIL_ADJUSTMENT (obj);
- gail_adjustment->adjustment = adjustment;
-
- g_object_add_weak_pointer (G_OBJECT (adjustment),
- (gpointer *) &gail_adjustment->adjustment);
-}
-
-static void
-atk_value_interface_init (AtkValueIface *iface)
-{
- iface->get_current_value = gail_adjustment_get_current_value;
- iface->get_maximum_value = gail_adjustment_get_maximum_value;
- iface->get_minimum_value = gail_adjustment_get_minimum_value;
- iface->get_minimum_increment = gail_adjustment_get_minimum_increment;
- iface->set_current_value = gail_adjustment_set_current_value;
-}
-
-static void
-gail_adjustment_get_current_value (AtkValue *obj,
- GValue *value)
-{
- GtkAdjustment* adjustment;
- gdouble current_value;
-
- adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
- if (adjustment == NULL)
- {
- /* State is defunct */
- return;
- }
-
- current_value = gtk_adjustment_get_value (adjustment);
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_DOUBLE);
- g_value_set_double (value,current_value);
-}
-
-static void
-gail_adjustment_get_maximum_value (AtkValue *obj,
- GValue *value)
-{
- GtkAdjustment* adjustment;
- gdouble maximum_value;
-
- adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
- if (adjustment == NULL)
- {
- /* State is defunct */
- return;
- }
-
- maximum_value = gtk_adjustment_get_upper (adjustment);
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_DOUBLE);
- g_value_set_double (value, maximum_value);
-}
-
-static void
-gail_adjustment_get_minimum_value (AtkValue *obj,
- GValue *value)
-{
- GtkAdjustment* adjustment;
- gdouble minimum_value;
-
- adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
- if (adjustment == NULL)
- {
- /* State is defunct */
- return;
- }
-
- minimum_value = gtk_adjustment_get_lower (adjustment);
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_DOUBLE);
- g_value_set_double (value, minimum_value);
-}
-
-static void
-gail_adjustment_get_minimum_increment (AtkValue *obj,
- GValue *value)
-{
- GtkAdjustment* adjustment;
- gdouble minimum_increment;
-
- adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
- if (adjustment == NULL)
- {
- /* State is defunct */
- return;
- }
-
- if (gtk_adjustment_get_step_increment (adjustment) != 0 &&
- gtk_adjustment_get_page_increment (adjustment) != 0)
- {
- if (ABS (gtk_adjustment_get_step_increment (adjustment)) < ABS (gtk_adjustment_get_page_increment (adjustment)))
- minimum_increment = gtk_adjustment_get_step_increment (adjustment);
- else
- minimum_increment = gtk_adjustment_get_page_increment (adjustment);
- }
- else if (gtk_adjustment_get_step_increment (adjustment) == 0 &&
- gtk_adjustment_get_page_increment (adjustment) == 0)
- {
- minimum_increment = 0;
- }
- else if (gtk_adjustment_get_step_increment (adjustment) == 0)
- {
- minimum_increment = gtk_adjustment_get_page_increment (adjustment);
- }
- else
- {
- minimum_increment = gtk_adjustment_get_step_increment (adjustment);
- }
-
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_DOUBLE);
- g_value_set_double (value, minimum_increment);
-}
-
-static gboolean
-gail_adjustment_set_current_value (AtkValue *obj,
- const GValue *value)
-{
- if (G_VALUE_HOLDS_DOUBLE (value))
- {
- GtkAdjustment* adjustment;
- gdouble new_value;
-
- adjustment = GAIL_ADJUSTMENT (obj)->adjustment;
- if (adjustment == NULL)
- {
- /* State is defunct */
- return FALSE;
- }
- new_value = g_value_get_double (value);
- gtk_adjustment_set_value (adjustment, new_value);
-
- return TRUE;
- }
- else
- return FALSE;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_ADJUSTMENT_H__
-#define __GAIL_ADJUSTMENT_H__
-
-#include <atk/atk.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_ADJUSTMENT (gail_adjustment_get_type ())
-#define GAIL_ADJUSTMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_ADJUSTMENT, GailAdjustment))
-#define GAIL_ADJUSTMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_ADJUSTMENT, GailAdjustmentClass))
-#define GAIL_IS_ADJUSTMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_ADJUSTMENT))
-#define GAIL_IS_ADJUSTMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_ADJUSTMENT))
-#define GAIL_ADJUSTMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_ADJUSTMENT, GailAdjustmentClass))
-
-typedef struct _GailAdjustment GailAdjustment;
-typedef struct _GailAdjustmentClass GailAdjustmentClass;
-
-struct _GailAdjustment
-{
- AtkObject parent;
-
- GtkAdjustment *adjustment;
-};
-
-GType gail_adjustment_get_type (void);
-
-struct _GailAdjustmentClass
-{
- AtkObjectClass parent_class;
-};
-
-AtkObject *gail_adjustment_new (GtkAdjustment *adjustment);
-
-G_END_DECLS
-
-#endif /* __GAIL_ADJUSTMENT_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailarrow.h"
-
-static void gail_arrow_class_init (GailArrowClass *klass);
-static void gail_arrow_init (GailArrow *arrow);
-static void gail_arrow_initialize (AtkObject *accessible,
- gpointer data);
-
-/* AtkImage */
-static void atk_image_interface_init (AtkImageIface *iface);
-static const gchar* gail_arrow_get_image_description
- (AtkImage *obj);
-static gboolean gail_arrow_set_image_description
- (AtkImage *obj,
- const gchar *description);
-static void gail_arrow_finalize (GObject *object);
-
-G_DEFINE_TYPE_WITH_CODE (GailArrow, gail_arrow, GAIL_TYPE_WIDGET,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init))
-
-static void
-gail_arrow_class_init (GailArrowClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
-
- atk_object_class->initialize = gail_arrow_initialize;
-
- gobject_class->finalize = gail_arrow_finalize;
-}
-
-static void
-gail_arrow_init (GailArrow *arrow)
-{
- arrow->image_description = NULL;
-}
-
-static void
-gail_arrow_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_arrow_parent_class)->initialize (accessible, data);
-
- accessible->role = ATK_ROLE_ICON;
-}
-
-static void
-atk_image_interface_init (AtkImageIface *iface)
-{
- iface->get_image_description = gail_arrow_get_image_description;
- iface->set_image_description = gail_arrow_set_image_description;
-}
-
-static const gchar*
-gail_arrow_get_image_description (AtkImage *obj)
-{
- GailArrow* arrow;
-
- g_return_val_if_fail(GAIL_IS_ARROW(obj), NULL);
-
- arrow = GAIL_ARROW (obj);
-
- return arrow->image_description;
-}
-
-static gboolean
-gail_arrow_set_image_description (AtkImage *obj,
- const gchar *description)
-{
- GailArrow* arrow;
-
- g_return_val_if_fail(GAIL_IS_ARROW(obj), FALSE);
-
- arrow = GAIL_ARROW (obj);
- g_free (arrow->image_description);
-
- arrow->image_description = g_strdup (description);
-
- return TRUE;
-
-}
-
-/*
- * static void
- * gail_arrow_get_image_size (AtkImage *obj,
- * gint *height,
- * gint *width)
- *
- * We dont implement this function for GailArrow as gtk hardcodes the size
- * of the arrow to be 7x5 and it is not possible to query this.
- */
-
-static void
-gail_arrow_finalize (GObject *object)
-{
- GailArrow *arrow = GAIL_ARROW (object);
-
- g_free (arrow->image_description);
- G_OBJECT_CLASS (gail_arrow_parent_class)->finalize (object);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_ARROW_H__
-#define __GAIL_ARROW_H__
-
-#include "gailwidget.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_ARROW (gail_arrow_get_type ())
-#define GAIL_ARROW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_ARROW, GailArrow))
-#define GAIL_ARROW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_ARROW, GailArrowClass))
-#define GAIL_IS_ARROW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_ARROW))
-#define GAIL_IS_ARROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_ARROW))
-#define GAIL_ARROW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_ARROW, GailArrowClass))
-
-typedef struct _GailArrow GailArrow;
-typedef struct _GailArrowClass GailArrowClass;
-
-struct _GailArrow
-{
- GailWidget parent;
-
- gchar* image_description;
-};
-
-GType gail_arrow_get_type (void);
-
-struct _GailArrowClass
-{
- GailWidgetClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_ARROW_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailbooleancell.h"
-
-static void gail_boolean_cell_class_init (GailBooleanCellClass *klass);
-static void gail_boolean_cell_init (GailBooleanCell *cell);
-/* Misc */
-
-static gboolean gail_boolean_cell_update_cache (GailRendererCell *cell,
- gboolean emit_change_signal);
-
-gchar *gail_boolean_cell_property_list[] = {
- "active",
- "radio",
- "sensitive",
- NULL
-};
-
-G_DEFINE_TYPE (GailBooleanCell, gail_boolean_cell, GAIL_TYPE_RENDERER_CELL)
-
-static void
-gail_boolean_cell_class_init (GailBooleanCellClass *klass)
-{
- GailRendererCellClass *renderer_cell_class = GAIL_RENDERER_CELL_CLASS (klass);
-
- renderer_cell_class->update_cache = gail_boolean_cell_update_cache;
- renderer_cell_class->property_list = gail_boolean_cell_property_list;
-}
-
-static void
-gail_boolean_cell_init (GailBooleanCell *cell)
-{
-}
-
-AtkObject*
-gail_boolean_cell_new (void)
-{
- GObject *object;
- AtkObject *atk_object;
- GailRendererCell *cell;
- GailBooleanCell *boolean_cell;
-
- object = g_object_new (GAIL_TYPE_BOOLEAN_CELL, NULL);
-
- g_return_val_if_fail (object != NULL, NULL);
-
- atk_object = ATK_OBJECT (object);
- atk_object->role = ATK_ROLE_TABLE_CELL;
-
- cell = GAIL_RENDERER_CELL(object);
- boolean_cell = GAIL_BOOLEAN_CELL(object);
-
- cell->renderer = gtk_cell_renderer_toggle_new ();
- g_object_ref_sink (cell->renderer);
- boolean_cell->cell_value = FALSE;
- boolean_cell->cell_sensitive = TRUE;
- return atk_object;
-}
-
-static gboolean
-gail_boolean_cell_update_cache (GailRendererCell *cell,
- gboolean emit_change_signal)
-{
- GailBooleanCell *boolean_cell = GAIL_BOOLEAN_CELL (cell);
- gboolean rv = FALSE;
- gboolean new_boolean;
- gboolean new_sensitive;
-
- g_object_get (G_OBJECT(cell->renderer), "active", &new_boolean,
- "sensitive", &new_sensitive, NULL);
-
- if (boolean_cell->cell_value != new_boolean)
- {
- rv = TRUE;
- boolean_cell->cell_value = !(boolean_cell->cell_value);
-
- /* Update cell's state */
-
- if (new_boolean)
- gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_CHECKED, emit_change_signal);
- else
- gail_cell_remove_state (GAIL_CELL (cell), ATK_STATE_CHECKED, emit_change_signal);
- }
-
- if (boolean_cell->cell_sensitive != new_sensitive)
- {
- rv = TRUE;
- boolean_cell->cell_sensitive = !(boolean_cell->cell_sensitive);
-
- /* Update cell's state */
-
- if (new_sensitive)
- gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_SENSITIVE, emit_change_signal);
- else
- gail_cell_remove_state (GAIL_CELL (cell), ATK_STATE_SENSITIVE, emit_change_signal);
- }
-
- return rv;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_BOOLEAN_CELL_H__
-#define __GAIL_BOOLEAN_CELL_H__
-
-#include <atk/atk.h>
-#include "gailrenderercell.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_BOOLEAN_CELL (gail_boolean_cell_get_type ())
-#define GAIL_BOOLEAN_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_BOOLEAN_CELL, GailBooleanCell))
-#define GAIL_BOOLEAN_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_BOOLEAN_CELL, GailBooleanCellClass))
-#define GAIL_IS_BOOLEAN_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_BOOLEAN_CELL))
-#define GAIL_IS_BOOLEAN_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_BOOLEAN_CELL))
-#define GAIL_BOOLEAN_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_BOOLEAN_CELL, GailBooleanCellClass))
-
-typedef struct _GailBooleanCell GailBooleanCell;
-typedef struct _GailBooleanCellClass GailBooleanCellClass;
-
-struct _GailBooleanCell
-{
- GailRendererCell parent;
- gboolean cell_value;
- gboolean cell_sensitive;
-};
-
- GType gail_boolean_cell_get_type (void);
-
-struct _GailBooleanCellClass
-{
- GailRendererCellClass parent_class;
-};
-
-AtkObject *gail_boolean_cell_new (void);
-
-G_END_DECLS
-
-#endif /* __GAIL_TREE_VIEW_BOOLEAN_CELL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailbox.h"
-
-static void gail_box_class_init (GailBoxClass *klass);
-static void gail_box_init (GailBox *box);
-static void gail_box_initialize (AtkObject *accessible,
- gpointer data);
-
-G_DEFINE_TYPE (GailBox, gail_box, GAIL_TYPE_CONTAINER)
-
-static void
-gail_box_class_init (GailBoxClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->initialize = gail_box_initialize;
-}
-
-static void
-gail_box_init (GailBox *box)
-{
-}
-
-static void
-gail_box_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_box_parent_class)->initialize (accessible, data);
-
- accessible->role = ATK_ROLE_FILLER;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_BOX_H__
-#define __GAIL_BOX_H__
-
-#include "gailcontainer.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_BOX (gail_box_get_type ())
-#define GAIL_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_BOX, GailBox))
-#define GAIL_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_BOX, GailBoxClass))
-#define GAIL_IS_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_BOX))
-#define GAIL_IS_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_BOX))
-#define GAIL_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_BOX, GailBoxClass))
-
-typedef struct _GailBox GailBox;
-typedef struct _GailBoxClass GailBoxClass;
-
-struct _GailBox
-{
- GailContainer parent;
-};
-
-GType gail_box_get_type (void);
-
-struct _GailBoxClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_BOX_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "gailbutton.h"
-#include <libgail-util/gailmisc.h>
-
-#define GAIL_BUTTON_ATTACHED_MENUS "gtk-attached-menus"
-
-static void gail_button_class_init (GailButtonClass *klass);
-static void gail_button_init (GailButton *button);
-
-static const gchar* gail_button_get_name (AtkObject *obj);
-static gint gail_button_get_n_children (AtkObject *obj);
-static AtkObject* gail_button_ref_child (AtkObject *obj,
- gint i);
-static AtkStateSet* gail_button_ref_state_set (AtkObject *obj);
-static void gail_button_notify_label_gtk (GObject *obj,
- GParamSpec *pspec,
- gpointer data);
-static void gail_button_label_map_gtk (GtkWidget *widget,
- gpointer data);
-
-static void gail_button_real_initialize (AtkObject *obj,
- gpointer data);
-static void gail_button_finalize (GObject *object);
-static void gail_button_init_textutil (GailButton *button,
- GtkWidget *label);
-
-static void gail_button_pressed_enter_handler (GtkWidget *widget);
-static void gail_button_released_leave_handler (GtkWidget *widget);
-static gint gail_button_real_add_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data);
-
-
-static void atk_action_interface_init (AtkActionIface *iface);
-static gboolean gail_button_do_action (AtkAction *action,
- gint i);
-static gboolean idle_do_action (gpointer data);
-static gint gail_button_get_n_actions (AtkAction *action);
-static const gchar* gail_button_get_description(AtkAction *action,
- gint i);
-static const gchar* gail_button_get_keybinding (AtkAction *action,
- gint i);
-static const gchar* gail_button_action_get_name(AtkAction *action,
- gint i);
-static gboolean gail_button_set_description(AtkAction *action,
- gint i,
- const gchar *desc);
-static void gail_button_notify_label_weak_ref (gpointer data,
- GObject *obj);
-static void gail_button_notify_weak_ref (gpointer data,
- GObject *obj);
-
-
-/* AtkImage.h */
-static void atk_image_interface_init (AtkImageIface *iface);
-static const gchar* gail_button_get_image_description
- (AtkImage *image);
-static void gail_button_get_image_position
- (AtkImage *image,
- gint *x,
- gint *y,
- AtkCoordType coord_type);
-static void gail_button_get_image_size (AtkImage *image,
- gint *width,
- gint *height);
-static gboolean gail_button_set_image_description
- (AtkImage *image,
- const gchar *description);
-
-/* atktext.h */
-static void atk_text_interface_init (AtkTextIface *iface);
-
-static gchar* gail_button_get_text (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gunichar gail_button_get_character_at_offset(AtkText *text,
- gint offset);
-static gchar* gail_button_get_text_before_offset(AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_button_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_button_get_text_after_offset(AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gint gail_button_get_character_count (AtkText *text);
-static void gail_button_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static gint gail_button_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static AtkAttributeSet* gail_button_get_run_attributes
- (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet* gail_button_get_default_attributes
- (AtkText *text);
-static GtkImage* get_image_from_button (GtkWidget *button);
-static GtkWidget* get_label_from_button (GtkWidget *button,
- gint index,
- gboolean allow_many);
-static gint get_n_labels_from_button (GtkWidget *button);
-static void set_role_for_button (AtkObject *accessible,
- GtkWidget *button);
-
-static gint get_n_attached_menus (GtkWidget *widget);
-static GtkWidget* get_nth_attached_menu (GtkWidget *widget,
- gint index);
-
-G_DEFINE_TYPE_WITH_CODE (GailButton, gail_button, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
-
-static void
-gail_button_class_init (GailButtonClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailContainerClass *container_class;
-
- container_class = (GailContainerClass*)klass;
-
- gobject_class->finalize = gail_button_finalize;
-
- class->get_name = gail_button_get_name;
- class->get_n_children = gail_button_get_n_children;
- class->ref_child = gail_button_ref_child;
- class->ref_state_set = gail_button_ref_state_set;
- class->initialize = gail_button_real_initialize;
-
- container_class->add_gtk = gail_button_real_add_gtk;
- container_class->remove_gtk = NULL;
-}
-
-static void
-gail_button_init (GailButton *button)
-{
- button->click_description = NULL;
- button->press_description = NULL;
- button->release_description = NULL;
- button->click_keybinding = NULL;
- button->action_queue = NULL;
- button->action_idle_handler = 0;
- button->textutil = NULL;
-}
-
-static const gchar*
-gail_button_get_name (AtkObject *obj)
-{
- const gchar* name = NULL;
-
- g_return_val_if_fail (GAIL_IS_BUTTON (obj), NULL);
-
- name = ATK_OBJECT_CLASS (gail_button_parent_class)->get_name (obj);
- if (name == NULL)
- {
- /*
- * Get the text on the label
- */
- GtkWidget *widget;
- GtkWidget *child;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- g_return_val_if_fail (GTK_IS_BUTTON (widget), NULL);
-
- child = get_label_from_button (widget, 0, FALSE);
- if (GTK_IS_LABEL (child))
- name = gtk_label_get_text (GTK_LABEL (child));
- else
- {
- GtkImage *image;
-
- image = get_image_from_button (widget);
- if (GTK_IS_IMAGE (image))
- {
- AtkObject *atk_obj;
-
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (image));
- name = atk_object_get_name (atk_obj);
- }
- }
- }
- return name;
-}
-
-/*
- * A DownArrow in a GtkToggltButton whose parent is not a ColorCombo
- * has press as default action.
- */
-static gboolean
-gail_button_is_default_press (GtkWidget *widget)
-{
- GtkArrowType arrow_type;
- GtkWidget *child;
- GtkWidget *parent;
- gboolean ret = FALSE;
- const gchar *parent_type_name;
-
- child = gtk_bin_get_child (GTK_BIN (widget));
- if (GTK_IS_ARROW (child))
- {
- g_object_get (child,
- "arrow_type", &arrow_type,
- NULL);
-
- if (arrow_type == GTK_ARROW_DOWN)
- {
- parent = gtk_widget_get_parent (widget);
- if (parent)
- {
- parent_type_name = g_type_name (G_OBJECT_TYPE (parent));
- if (g_strcmp0 (parent_type_name, "ColorCombo"))
- return TRUE;
- }
- }
- }
-
- return ret;
-}
-
-static void
-gail_button_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GailButton *button = GAIL_BUTTON (obj);
- GtkWidget *label;
- GtkWidget *widget;
-
- ATK_OBJECT_CLASS (gail_button_parent_class)->initialize (obj, data);
-
- button->state = GTK_STATE_NORMAL;
-
- g_signal_connect (data,
- "pressed",
- G_CALLBACK (gail_button_pressed_enter_handler),
- NULL);
- g_signal_connect (data,
- "enter",
- G_CALLBACK (gail_button_pressed_enter_handler),
- NULL);
- g_signal_connect (data,
- "released",
- G_CALLBACK (gail_button_released_leave_handler),
- NULL);
- g_signal_connect (data,
- "leave",
- G_CALLBACK (gail_button_released_leave_handler),
- NULL);
-
-
- widget = GTK_WIDGET (data);
- label = get_label_from_button (widget, 0, FALSE);
- if (GTK_IS_LABEL (label))
- {
- if (gtk_widget_get_mapped (label))
- gail_button_init_textutil (button, label);
- else
- g_signal_connect (label,
- "map",
- G_CALLBACK (gail_button_label_map_gtk),
- button);
- }
- button->default_is_press = gail_button_is_default_press (widget);
-
- set_role_for_button (obj, data);
-}
-
-static void
-gail_button_label_map_gtk (GtkWidget *widget,
- gpointer data)
-{
- GailButton *button;
-
- button = GAIL_BUTTON (data);
- gail_button_init_textutil (button, widget);
-}
-
-static void
-gail_button_notify_label_gtk (GObject *obj,
- GParamSpec *pspec,
- gpointer data)
-{
- AtkObject* atk_obj = ATK_OBJECT (data);
- GtkLabel *label;
- GailButton *gail_button;
-
- if (strcmp (pspec->name, "label") == 0)
- {
- const gchar* label_text;
-
- label = GTK_LABEL (obj);
-
- label_text = gtk_label_get_text (label);
-
- gail_button = GAIL_BUTTON (atk_obj);
- gail_text_util_text_setup (gail_button->textutil, label_text);
-
- if (atk_obj->name == NULL)
- {
- /*
- * The label has changed so notify a change in accessible-name
- */
- g_object_notify (G_OBJECT (atk_obj), "accessible-name");
- }
- /*
- * The label is the only property which can be changed
- */
- g_signal_emit_by_name (atk_obj, "visible_data_changed");
- }
-}
-
-static void
-gail_button_notify_weak_ref (gpointer data, GObject* obj)
-{
- GtkLabel *label = NULL;
-
- AtkObject* atk_obj = ATK_OBJECT (obj);
- if (data && GTK_IS_WIDGET (data))
- {
- label = GTK_LABEL (data);
- if (label)
- {
- g_signal_handlers_disconnect_by_func (label,
- (GCallback) gail_button_notify_label_gtk,
- GAIL_BUTTON (atk_obj));
- g_object_weak_unref (G_OBJECT (label),
- gail_button_notify_label_weak_ref,
- GAIL_BUTTON (atk_obj));
- }
- }
-}
-
-static void
-gail_button_notify_label_weak_ref (gpointer data, GObject* obj)
-{
- GtkLabel *label = NULL;
- GailButton *button = NULL;
-
- label = GTK_LABEL (obj);
- if (data && GAIL_IS_BUTTON (data))
- {
- button = GAIL_BUTTON (ATK_OBJECT (data));
- if (button)
- g_object_weak_unref (G_OBJECT (button), gail_button_notify_weak_ref,
- label);
- }
-}
-
-
-static void
-gail_button_init_textutil (GailButton *button,
- GtkWidget *label)
-{
- const gchar *label_text;
-
- if (button->textutil)
- g_object_unref (button->textutil);
- button->textutil = gail_text_util_new ();
- label_text = gtk_label_get_text (GTK_LABEL (label));
- gail_text_util_text_setup (button->textutil, label_text);
- g_object_weak_ref (G_OBJECT (button),
- gail_button_notify_weak_ref, label);
- g_object_weak_ref (G_OBJECT (label),
- gail_button_notify_label_weak_ref, button);
- g_signal_connect (label,
- "notify",
- (GCallback) gail_button_notify_label_gtk,
- button);
-}
-
-static gint
-gail_button_real_add_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data)
-{
- GtkLabel *label;
- GailButton *button;
-
- if (GTK_IS_LABEL (widget))
- {
- const gchar* label_text;
-
- label = GTK_LABEL (widget);
-
-
- button = GAIL_BUTTON (data);
- if (!button->textutil)
- gail_button_init_textutil (button, widget);
- else
- {
- label_text = gtk_label_get_text (label);
- gail_text_util_text_setup (button->textutil, label_text);
- }
- }
-
- return 1;
-}
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- iface->do_action = gail_button_do_action;
- iface->get_n_actions = gail_button_get_n_actions;
- iface->get_description = gail_button_get_description;
- iface->get_keybinding = gail_button_get_keybinding;
- iface->get_name = gail_button_action_get_name;
- iface->set_description = gail_button_set_description;
-}
-
-static gboolean
-gail_button_do_action (AtkAction *action,
- gint i)
-{
- GtkWidget *widget;
- GailButton *button;
- gboolean return_value = TRUE;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- button = GAIL_BUTTON (action);
-
- switch (i)
- {
- case 0:
- case 1:
- case 2:
- if (!button->action_queue)
- {
- button->action_queue = g_queue_new ();
- }
- g_queue_push_head (button->action_queue, GINT_TO_POINTER(i));
- if (!button->action_idle_handler)
- button->action_idle_handler = gdk_threads_add_idle (idle_do_action, button);
- break;
- default:
- return_value = FALSE;
- break;
- }
- return return_value;
-}
-
-static gboolean
-idle_do_action (gpointer data)
-{
- GtkButton *button;
- GtkWidget *widget;
- GailButton *gail_button;
- GdkEvent tmp_event;
- GdkWindow *window;
-
- gail_button = GAIL_BUTTON (data);
- gail_button->action_idle_handler = 0;
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gail_button));
- window = gtk_widget_get_window (widget);
-
- tmp_event.button.type = GDK_BUTTON_RELEASE;
- tmp_event.button.window = window;
- tmp_event.button.button = 1;
- tmp_event.button.send_event = TRUE;
- tmp_event.button.time = GDK_CURRENT_TIME;
- tmp_event.button.axes = NULL;
-
- g_object_ref (gail_button);
-
- if (widget == NULL /* State is defunct */ ||
- !gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
- {
- g_object_unref (gail_button);
- return FALSE;
- }
- else
- gtk_widget_event (widget, &tmp_event);
-
- button = GTK_BUTTON (widget);
- while (!g_queue_is_empty (gail_button->action_queue))
- {
- gint action_number = GPOINTER_TO_INT(g_queue_pop_head (gail_button->action_queue));
- if (gail_button->default_is_press)
- {
- if (action_number == 0)
- action_number = 1;
- else if (action_number == 1)
- action_number = 0;
- }
- switch (action_number)
- {
- case 0:
- /* first a press */
-
- /* FIXME: Do not access public member
- button->in_button = TRUE;
- */
- g_signal_emit_by_name (button, "enter");
- /*
- * Simulate a button press event. calling gtk_button_pressed() does
- * not get the job done for a GtkOptionMenu.
- */
- tmp_event.button.type = GDK_BUTTON_PRESS;
- tmp_event.button.window = window;
- tmp_event.button.button = 1;
- tmp_event.button.send_event = TRUE;
- tmp_event.button.time = GDK_CURRENT_TIME;
- tmp_event.button.axes = NULL;
-
- gtk_widget_event (widget, &tmp_event);
-
- /* then a release */
- tmp_event.button.type = GDK_BUTTON_RELEASE;
- gtk_widget_event (widget, &tmp_event);
- /* FIXME: Do not access public member
- button->in_button = FALSE;
- */
- g_signal_emit_by_name (button, "leave");
- break;
- case 1:
- /* FIXME: Do not access public member
- button->in_button = TRUE;
- */
- g_signal_emit_by_name (button, "enter");
- /*
- * Simulate a button press event. calling gtk_button_pressed() does
- * not get the job done for a GtkOptionMenu.
- */
- tmp_event.button.type = GDK_BUTTON_PRESS;
- tmp_event.button.window = window;
- tmp_event.button.button = 1;
- tmp_event.button.send_event = TRUE;
- tmp_event.button.time = GDK_CURRENT_TIME;
- tmp_event.button.axes = NULL;
-
- gtk_widget_event (widget, &tmp_event);
- break;
- case 2:
- /* FIXME: Do not access public member
- button->in_button = FALSE;
- */
- g_signal_emit_by_name (button, "leave");
- break;
- default:
- g_assert_not_reached ();
- break;
- }
- }
- g_object_unref (gail_button);
- return FALSE;
-}
-
-static gint
-gail_button_get_n_actions (AtkAction *action)
-{
- return 3;
-}
-
-static const gchar*
-gail_button_get_description (AtkAction *action,
- gint i)
-{
- GailButton *button;
- const gchar *return_value;
-
- button = GAIL_BUTTON (action);
-
- if (button->default_is_press)
- {
- if (i == 0)
- i = 1;
- else if (i == 1)
- i = 0;
- }
- switch (i)
- {
- case 0:
- return_value = button->click_description;
- break;
- case 1:
- return_value = button->press_description;
- break;
- case 2:
- return_value = button->release_description;
- break;
- default:
- return_value = NULL;
- break;
- }
- return return_value;
-}
-
-static const gchar*
-gail_button_get_keybinding (AtkAction *action,
- gint i)
-{
- GailButton *button;
- gchar *return_value = NULL;
-
- button = GAIL_BUTTON (action);
- if (button->default_is_press)
- {
- if (i == 0)
- i = 1;
- else if (i == 1)
- i = 0;
- }
- switch (i)
- {
- case 0:
- {
- /*
- * We look for a mnemonic on the label
- */
- GtkWidget *widget;
- GtkWidget *label;
- guint key_val;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (button));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- g_return_val_if_fail (GTK_IS_BUTTON (widget), NULL);
-
- label = get_label_from_button (widget, 0, FALSE);
- if (GTK_IS_LABEL (label))
- {
- key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
- if (key_val != GDK_KEY_VoidSymbol)
- return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
- }
- if (return_value == NULL)
- {
- /* Find labelled-by relation */
- AtkRelationSet *set;
- AtkRelation *relation;
- GPtrArray *target;
- gpointer target_object;
-
- set = atk_object_ref_relation_set (ATK_OBJECT (action));
- if (set)
- {
- relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
- if (relation)
- {
- target = atk_relation_get_target (relation);
-
- target_object = g_ptr_array_index (target, 0);
- label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
- }
- g_object_unref (set);
- }
-
- if (GTK_IS_LABEL (label))
- {
- key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
- if (key_val != GDK_KEY_VoidSymbol)
- return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
- }
- }
- g_free (button->click_keybinding);
- button->click_keybinding = return_value;
- break;
- }
- default:
- break;
- }
- return return_value;
-}
-
-static const gchar*
-gail_button_action_get_name (AtkAction *action,
- gint i)
-{
- const gchar *return_value;
- GailButton *button;
-
- button = GAIL_BUTTON (action);
-
- if (button->default_is_press)
- {
- if (i == 0)
- i = 1;
- else if (i == 1)
- i = 0;
- }
- switch (i)
- {
- case 0:
- /*
- * This action is a "click" to activate a button or "toggle" to change
- * the state of a toggle button check box or radio button.
- */
- return_value = "click";
- break;
- case 1:
- /*
- * This action simulates a button press by simulating moving the
- * mouse into the button followed by pressing the left mouse button.
- */
- return_value = "press";
- break;
- case 2:
- /*
- * This action simulates releasing the left mouse button outside the
- * button.
- *
- * To simulate releasing the left mouse button inside the button use
- * the click action.
- */
- return_value = "release";
- break;
- default:
- return_value = NULL;
- break;
- }
- return return_value;
-}
-
-static gboolean
-gail_button_set_description (AtkAction *action,
- gint i,
- const gchar *desc)
-{
- GailButton *button;
- gchar **value;
-
- button = GAIL_BUTTON (action);
-
- if (button->default_is_press)
- {
- if (i == 0)
- i = 1;
- else if (i == 1)
- i = 0;
- }
- switch (i)
- {
- case 0:
- value = &button->click_description;
- break;
- case 1:
- value = &button->press_description;
- break;
- case 2:
- value = &button->release_description;
- break;
- default:
- value = NULL;
- break;
- }
- if (value)
- {
- g_free (*value);
- *value = g_strdup (desc);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gint
-gail_button_get_n_children (AtkObject* obj)
-{
- GtkWidget *widget;
- gint n_children;
-
- g_return_val_if_fail (GAIL_IS_BUTTON (obj), 0);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return 0;
-
- /*
- * Check whether we have an attached menus for PanelMenuButton
- */
- n_children = get_n_attached_menus (widget);
- if (n_children > 0)
- return n_children;
-
- n_children = get_n_labels_from_button (widget);
- if (n_children <= 1)
- n_children = 0;
-
- return n_children;
-}
-
-static AtkObject*
-gail_button_ref_child (AtkObject *obj,
- gint i)
-{
- GtkWidget *widget;
- GtkWidget *child_widget;
- AtkObject *child;
-
- g_return_val_if_fail (GAIL_IS_BUTTON (obj), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- if (i >= gail_button_get_n_children (obj))
- return NULL;
-
- if (get_n_attached_menus (widget) > 0)
- {
- child_widget = get_nth_attached_menu (widget, i);
- }
- else
- child_widget = NULL;
-
- if (!child_widget)
- {
- if (get_n_labels_from_button (widget) > 1)
- {
- child_widget = get_label_from_button (widget, i, TRUE);
- }
- }
-
- if (child_widget)
- {
- child = gtk_widget_get_accessible (child_widget);
- g_object_ref (child);
- }
- else
- child = NULL;
-
- return child;
-}
-
-static AtkStateSet*
-gail_button_ref_state_set (AtkObject *obj)
-{
- AtkStateSet *state_set;
- GtkWidget *widget;
-
- state_set = ATK_OBJECT_CLASS (gail_button_parent_class)->ref_state_set (obj);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
-
- if (widget == NULL)
- return state_set;
-
- if (gtk_widget_get_state (widget) == GTK_STATE_ACTIVE)
- atk_state_set_add_state (state_set, ATK_STATE_ARMED);
-
- if (!gtk_widget_get_can_focus (widget))
- atk_state_set_remove_state (state_set, ATK_STATE_SELECTABLE);
-
-
- return state_set;
-}
-
-/*
- * This is the signal handler for the "pressed" or "enter" signal handler
- * on the GtkButton.
- *
- * If the state is now GTK_STATE_ACTIVE we notify a property change
- */
-static void
-gail_button_pressed_enter_handler (GtkWidget *widget)
-{
- AtkObject *accessible;
-
- if (gtk_widget_get_state (widget) == GTK_STATE_ACTIVE)
- {
- accessible = gtk_widget_get_accessible (widget);
- atk_object_notify_state_change (accessible, ATK_STATE_ARMED, TRUE);
- GAIL_BUTTON (accessible)->state = GTK_STATE_ACTIVE;
- }
-}
-
-/*
- * This is the signal handler for the "released" or "leave" signal handler
- * on the GtkButton.
- *
- * If the state was GTK_STATE_ACTIVE we notify a property change
- */
-static void
-gail_button_released_leave_handler (GtkWidget *widget)
-{
- AtkObject *accessible;
-
- accessible = gtk_widget_get_accessible (widget);
- if (GAIL_BUTTON (accessible)->state == GTK_STATE_ACTIVE)
- {
- atk_object_notify_state_change (accessible, ATK_STATE_ARMED, FALSE);
- GAIL_BUTTON (accessible)->state = GTK_STATE_NORMAL;
- }
-}
-
-static void
-atk_image_interface_init (AtkImageIface *iface)
-{
- iface->get_image_description = gail_button_get_image_description;
- iface->get_image_position = gail_button_get_image_position;
- iface->get_image_size = gail_button_get_image_size;
- iface->set_image_description = gail_button_set_image_description;
-}
-
-static GtkImage*
-get_image_from_button (GtkWidget *button)
-{
- GtkWidget *child;
- GList *list;
- GtkImage *image = NULL;
-
- child = gtk_bin_get_child (GTK_BIN (button));
- if (GTK_IS_IMAGE (child))
- image = GTK_IMAGE (child);
- else
- {
- if (GTK_IS_ALIGNMENT (child))
- child = gtk_bin_get_child (GTK_BIN (child));
- if (GTK_IS_CONTAINER (child))
- {
- list = gtk_container_get_children (GTK_CONTAINER (child));
- if (!list)
- return NULL;
- if (GTK_IS_IMAGE (list->data))
- image = GTK_IMAGE (list->data);
- g_list_free (list);
- }
- }
-
- return image;
-}
-
-static const gchar*
-gail_button_get_image_description (AtkImage *image) {
-
- GtkWidget *widget;
- GtkImage *button_image;
- AtkObject *obj;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- button_image = get_image_from_button (widget);
-
- if (button_image != NULL)
- {
- obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
- return atk_image_get_image_description (ATK_IMAGE (obj));
- }
- else
- return NULL;
-}
-
-static void
-gail_button_get_image_position (AtkImage *image,
- gint *x,
- gint *y,
- AtkCoordType coord_type)
-{
- GtkWidget *widget;
- GtkImage *button_image;
- AtkObject *obj;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
-
- if (widget == NULL)
- {
- /*
- * State is defunct
- */
- *x = G_MININT;
- *y = G_MININT;
- return;
- }
-
- button_image = get_image_from_button (widget);
-
- if (button_image != NULL)
- {
- obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
- atk_component_get_position (ATK_COMPONENT (obj), x, y, coord_type);
- }
- else
- {
- *x = G_MININT;
- *y = G_MININT;
- }
-}
-
-static void
-gail_button_get_image_size (AtkImage *image,
- gint *width,
- gint *height)
-{
- GtkWidget *widget;
- GtkImage *button_image;
- AtkObject *obj;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
-
- if (widget == NULL)
- {
- /*
- * State is defunct
- */
- *width = -1;
- *height = -1;
- return;
- }
-
- button_image = get_image_from_button (widget);
-
- if (button_image != NULL)
- {
- obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
- atk_image_get_image_size (ATK_IMAGE (obj), width, height);
- }
- else
- {
- *width = -1;
- *height = -1;
- }
-}
-
-static gboolean
-gail_button_set_image_description (AtkImage *image,
- const gchar *description)
-{
- GtkWidget *widget;
- GtkImage *button_image;
- AtkObject *obj;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- button_image = get_image_from_button (widget);
-
- if (button_image != NULL)
- {
- obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
- return atk_image_set_image_description (ATK_IMAGE (obj), description);
- }
- else
- return FALSE;
-}
-
-/* atktext.h */
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_button_get_text;
- iface->get_character_at_offset = gail_button_get_character_at_offset;
- iface->get_text_before_offset = gail_button_get_text_before_offset;
- iface->get_text_at_offset = gail_button_get_text_at_offset;
- iface->get_text_after_offset = gail_button_get_text_after_offset;
- iface->get_character_count = gail_button_get_character_count;
- iface->get_character_extents = gail_button_get_character_extents;
- iface->get_offset_at_point = gail_button_get_offset_at_point;
- iface->get_run_attributes = gail_button_get_run_attributes;
- iface->get_default_attributes = gail_button_get_default_attributes;
-}
-
-static gchar*
-gail_button_get_text (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailButton *button;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL (label))
- return NULL;
-
- button = GAIL_BUTTON (text);
- if (!button->textutil)
- gail_button_init_textutil (button, label);
-
- label_text = gtk_label_get_text (GTK_LABEL (label));
-
- if (label_text == NULL)
- return NULL;
- else
- {
- return gail_text_util_get_substring (button->textutil,
- start_pos, end_pos);
- }
-}
-
-static gchar*
-gail_button_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailButton *button;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get label */
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- button = GAIL_BUTTON (text);
- if (!button->textutil)
- gail_button_init_textutil (button, label);
-
- return gail_text_util_get_text (button->textutil,
- gtk_label_get_layout (GTK_LABEL (label)), GAIL_BEFORE_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_button_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailButton *button;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get label */
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- button = GAIL_BUTTON (text);
- if (!button->textutil)
- gail_button_init_textutil (button, label);
-
- return gail_text_util_get_text (button->textutil,
- gtk_label_get_layout (GTK_LABEL (label)), GAIL_AT_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_button_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailButton *button;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- {
- /* State is defunct */
- return NULL;
- }
-
- /* Get label */
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- button = GAIL_BUTTON (text);
- if (!button->textutil)
- gail_button_init_textutil (button, label);
-
- return gail_text_util_get_text (button->textutil,
- gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gint
-gail_button_get_character_count (AtkText *text)
-{
- GtkWidget *widget;
- GtkWidget *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL(label))
- return 0;
-
- return g_utf8_strlen (gtk_label_get_text (GTK_LABEL (label)), -1);
-}
-
-static void
-gail_button_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkWidget *label;
- PangoRectangle char_rect;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return;
-
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL(label))
- return;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
- pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
-
- gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
- x_layout, y_layout, x, y, width, height, coords);
-}
-
-static gint
-gail_button_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkWidget *label;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL(label))
- return -1;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
-
- index = gail_misc_get_index_at_point_in_layout (label,
- gtk_label_get_layout (GTK_LABEL (label)),
- x_layout, y_layout, x, y, coords);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- if (index == -1)
- {
- if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
- return g_utf8_strlen (label_text, -1);
-
- return index;
- }
- else
- return g_utf8_pointer_to_offset (label_text, label_text + index);
-}
-
-static AtkAttributeSet*
-gail_button_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- AtkAttributeSet *at_set = NULL;
- GtkJustification justify;
- GtkTextDirection dir;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- /* Get values set for entire label, if any */
- justify = gtk_label_get_justify (GTK_LABEL (label));
- if (justify != GTK_JUSTIFY_CENTER)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_JUSTIFICATION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
- }
- dir = gtk_widget_get_direction (label);
- if (dir == GTK_TEXT_DIR_RTL)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_DIRECTION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
- }
-
- at_set = gail_misc_layout_get_run_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- (gchar *) gtk_label_get_text (GTK_LABEL (label)),
- offset,
- start_offset,
- end_offset);
- return at_set;
-}
-
-static AtkAttributeSet*
-gail_button_get_default_attributes (AtkText *text)
-{
- GtkWidget *widget;
- GtkWidget *label;
- AtkAttributeSet *at_set = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- at_set = gail_misc_get_default_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- widget);
- return at_set;
-}
-
-static gunichar
-gail_button_get_character_at_offset (AtkText *text,
- gint offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- const gchar *string;
- gchar *index;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return '\0';
-
- label = get_label_from_button (widget, 0, FALSE);
-
- if (!GTK_IS_LABEL(label))
- return '\0';
- string = gtk_label_get_text (GTK_LABEL (label));
- if (offset >= g_utf8_strlen (string, -1))
- return '\0';
- index = g_utf8_offset_to_pointer (string, offset);
-
- return g_utf8_get_char (index);
-}
-
-static void
-gail_button_finalize (GObject *object)
-{
- GailButton *button = GAIL_BUTTON (object);
-
- g_free (button->click_description);
- g_free (button->press_description);
- g_free (button->release_description);
- g_free (button->click_keybinding);
- if (button->action_idle_handler)
- {
- g_source_remove (button->action_idle_handler);
- button->action_idle_handler = 0;
- }
- if (button->action_queue)
- {
- g_queue_free (button->action_queue);
- }
- if (button->textutil)
- {
- g_object_unref (button->textutil);
- }
- G_OBJECT_CLASS (gail_button_parent_class)->finalize (object);
-}
-
-static GtkWidget*
-find_label_child (GtkContainer *container,
- gint *index,
- gboolean allow_many)
-{
- GList *children, *tmp_list;
- GtkWidget *child;
-
- children = gtk_container_get_children (container);
-
- child = NULL;
- for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
- {
- if (GTK_IS_LABEL (tmp_list->data))
- {
- if (!allow_many)
- {
- if (child)
- {
- child = NULL;
- break;
- }
- child = GTK_WIDGET (tmp_list->data);
- }
- else
- {
- if (*index == 0)
- {
- child = GTK_WIDGET (tmp_list->data);
- break;
- }
- (*index)--;
- }
- }
- /*
- * Label for button which are GtkTreeView column headers are in a
- * GtkHBox in a GtkAlignment.
- */
- else if (GTK_IS_ALIGNMENT (tmp_list->data))
- {
- GtkWidget *widget;
-
- widget = gtk_bin_get_child (GTK_BIN (tmp_list->data));
- if (GTK_IS_LABEL (widget))
- {
- if (!allow_many)
- {
- if (child)
- {
- child = NULL;
- break;
- }
- child = widget;
- }
- else
- {
- if (*index == 0)
- {
- child = widget;
- break;
- }
- (*index)--;
- }
- }
- }
- else if (GTK_IS_CONTAINER (tmp_list->data))
- {
- child = find_label_child (GTK_CONTAINER (tmp_list->data), index, allow_many);
- if (child)
- break;
- }
- }
- g_list_free (children);
- return child;
-}
-
-static GtkWidget*
-get_label_from_button (GtkWidget *button,
- gint index,
- gboolean allow_many)
-{
- GtkWidget *child;
-
- if (index > 0 && !allow_many)
- g_warning ("Inconsistent values passed to get_label_from_button");
-
- child = gtk_bin_get_child (GTK_BIN (button));
- if (GTK_IS_ALIGNMENT (child))
- child = gtk_bin_get_child (GTK_BIN (child));
-
- if (GTK_IS_CONTAINER (child))
- child = find_label_child (GTK_CONTAINER (child), &index, allow_many);
- else if (!GTK_IS_LABEL (child))
- child = NULL;
-
- return child;
-}
-
-static void
-count_labels (GtkContainer *container,
- gint *n_labels)
-{
- GList *children, *tmp_list;
-
- children = gtk_container_get_children (container);
-
- for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
- {
- if (GTK_IS_LABEL (tmp_list->data))
- {
- (*n_labels)++;
- }
- /*
- * Label for button which are GtkTreeView column headers are in a
- * GtkHBox in a GtkAlignment.
- */
- else if (GTK_IS_ALIGNMENT (tmp_list->data))
- {
- GtkWidget *widget;
-
- widget = gtk_bin_get_child (GTK_BIN (tmp_list->data));
- if (GTK_IS_LABEL (widget))
- (*n_labels)++;
- }
- else if (GTK_IS_CONTAINER (tmp_list->data))
- {
- count_labels (GTK_CONTAINER (tmp_list->data), n_labels);
- }
- }
- g_list_free (children);
-}
-
-static gint
-get_n_labels_from_button (GtkWidget *button)
-{
- GtkWidget *child;
- gint n_labels;
-
- n_labels = 0;
-
- child = gtk_bin_get_child (GTK_BIN (button));
- if (GTK_IS_ALIGNMENT (child))
- child = gtk_bin_get_child (GTK_BIN (child));
-
- if (GTK_IS_CONTAINER (child))
- count_labels (GTK_CONTAINER (child), &n_labels);
-
- return n_labels;
-}
-
-static void
-set_role_for_button (AtkObject *accessible,
- GtkWidget *button)
-{
- GtkWidget *parent;
- AtkRole role;
-
- parent = gtk_widget_get_parent (button);
- if (GTK_IS_TREE_VIEW (parent))
- {
- role = ATK_ROLE_TABLE_COLUMN_HEADER;
- /*
- * Even though the accessible parent of the column header will
- * be reported as the table because the parent widget of the
- * GtkTreeViewColumn's button is the GtkTreeView we set
- * the accessible parent for column header to be the table
- * to ensure that atk_object_get_index_in_parent() returns
- * the correct value; see gail_widget_get_index_in_parent().
- */
- atk_object_set_parent (accessible, gtk_widget_get_accessible (parent));
- }
- else
- role = ATK_ROLE_PUSH_BUTTON;
-
- accessible->role = role;
-}
-
-static gint
-get_n_attached_menus (GtkWidget *widget)
-{
- GList *list_menus;
-
- if (widget == NULL)
- return 0;
-
- list_menus = g_object_get_data (G_OBJECT (widget), GAIL_BUTTON_ATTACHED_MENUS);
- if (list_menus == NULL)
- return 0;
-
- return g_list_length (list_menus);
-}
-
-static GtkWidget*
-get_nth_attached_menu (GtkWidget *widget,
- gint index)
-{
- GtkWidget *attached_menu;
- GList *list_menus;
-
- if (widget == NULL)
- return NULL;
-
- list_menus = g_object_get_data (G_OBJECT (widget), GAIL_BUTTON_ATTACHED_MENUS);
- if (list_menus == NULL ||
- index >= g_list_length (list_menus))
- return NULL;
-
- attached_menu = (GtkWidget *) g_list_nth_data (list_menus, index);
-
- return attached_menu;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_BUTTON_H__
-#define __GAIL_BUTTON_H__
-
-#include "gailcontainer.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_BUTTON (gail_button_get_type ())
-#define GAIL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_BUTTON, GailButton))
-#define GAIL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_BUTTON, GailButtonClass))
-#define GAIL_IS_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_BUTTON))
-#define GAIL_IS_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_BUTTON))
-#define GAIL_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_BUTTON, GailButtonClass))
-
-typedef struct _GailButton GailButton;
-typedef struct _GailButtonClass GailButtonClass;
-
-struct _GailButton
-{
- GailContainer parent;
-
- /*
- * Cache the widget state so we know the previous state when it changed
- */
- gint8 state;
-
- gchar *click_description;
- gchar *press_description;
- gchar *release_description;
- gchar *click_keybinding;
- guint action_idle_handler;
- GQueue *action_queue;
-
- GailTextUtil *textutil;
-
- gboolean default_is_press;
-};
-
-GType gail_button_get_type (void);
-
-struct _GailButtonClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_BUTTON_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailcalendar.h"
-
-static void gail_calendar_class_init (GailCalendarClass *klass);
-static void gail_calendar_init (GailCalendar *calendar);
-static void gail_calendar_initialize (AtkObject *accessible,
- gpointer data);
-
-G_DEFINE_TYPE (GailCalendar, gail_calendar, GAIL_TYPE_WIDGET)
-
-static void
-gail_calendar_class_init (GailCalendarClass *klass)
-{
- AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
-
- atk_object_class->initialize = gail_calendar_initialize;
-}
-
-static void
-gail_calendar_init (GailCalendar *calendar)
-{
-}
-
-static void
-gail_calendar_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_calendar_parent_class)->initialize (accessible, data);
-
- accessible->role = ATK_ROLE_CALENDAR;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_CALENDAR_H__
-#define __GAIL_CALENDAR_H__
-
-#include "gailcontainer.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_CALENDAR (gail_calendar_get_type ())
-#define GAIL_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CALENDAR, GailCalendar))
-#define GAIL_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CALENDAR, GailCalendarClass))
-#define GAIL_IS_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CALENDAR))
-#define GAIL_IS_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CALENDAR))
-#define GAIL_CALENDAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CALENDAR, GailCalendarClass))
-
-typedef struct _GailCalendar GailCalendar;
-typedef struct _GailCalendarClass GailCalendarClass;
-
-struct _GailCalendar
-{
- GailWidget parent;
-};
-
-GType gail_calendar_get_type (void);
-
-struct _GailCalendarClass
-{
- GailWidgetClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_CALENDAR_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <gtk/gtk.h>
-#include "gailcontainercell.h"
-#include "gailcell.h"
-#include "gailcellparent.h"
-
-static void gail_cell_class_init (GailCellClass *klass);
-static void gail_cell_destroyed (GtkWidget *widget,
- GailCell *cell);
-
-static void gail_cell_init (GailCell *cell);
-static void gail_cell_object_finalize (GObject *cell);
-static AtkStateSet* gail_cell_ref_state_set (AtkObject *obj);
-static gint gail_cell_get_index_in_parent (AtkObject *obj);
-
-/* AtkAction */
-
-static void atk_action_interface_init
- (AtkActionIface *iface);
-static ActionInfo * _gail_cell_get_action_info (GailCell *cell,
- gint index);
-static void _gail_cell_destroy_action_info
- (gpointer data,
- gpointer user_data);
-
-static gint gail_cell_action_get_n_actions
- (AtkAction *action);
-static const gchar*
- gail_cell_action_get_name (AtkAction *action,
- gint index);
-static const gchar *
- gail_cell_action_get_description
- (AtkAction *action,
- gint index);
-static gboolean gail_cell_action_set_description
- (AtkAction *action,
- gint index,
- const gchar *desc);
-static const gchar *
- gail_cell_action_get_keybinding
- (AtkAction *action,
- gint index);
-static gboolean gail_cell_action_do_action (AtkAction *action,
- gint index);
-static gboolean idle_do_action (gpointer data);
-
-static void atk_component_interface_init (AtkComponentIface *iface);
-static void gail_cell_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type);
-static gboolean gail_cell_grab_focus (AtkComponent *component);
-
-G_DEFINE_TYPE_WITH_CODE (GailCell, gail_cell, ATK_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
-
-static void
-gail_cell_class_init (GailCellClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
-
- g_object_class->finalize = gail_cell_object_finalize;
-
- class->get_index_in_parent = gail_cell_get_index_in_parent;
- class->ref_state_set = gail_cell_ref_state_set;
-}
-
-void
-gail_cell_initialise (GailCell *cell,
- GtkWidget *widget,
- AtkObject *parent,
- gint index)
-{
- g_return_if_fail (GAIL_IS_CELL (cell));
- g_return_if_fail (GTK_IS_WIDGET (widget));
-
- cell->widget = widget;
- atk_object_set_parent (ATK_OBJECT (cell), parent);
- cell->index = index;
-
- g_signal_connect_object (G_OBJECT (widget),
- "destroy",
- G_CALLBACK (gail_cell_destroyed ),
- cell, 0);
-}
-
-static void
-gail_cell_destroyed (GtkWidget *widget,
- GailCell *cell)
-{
- /*
- * This is the signal handler for the "destroy" signal for the
- * GtkWidget. We set the pointer location to NULL;
- */
- cell->widget = NULL;
-}
-
-static void
-gail_cell_init (GailCell *cell)
-{
- cell->state_set = atk_state_set_new ();
- cell->widget = NULL;
- cell->action_list = NULL;
- cell->index = 0;
- atk_state_set_add_state (cell->state_set, ATK_STATE_TRANSIENT);
- atk_state_set_add_state (cell->state_set, ATK_STATE_ENABLED);
- atk_state_set_add_state (cell->state_set, ATK_STATE_SENSITIVE);
- atk_state_set_add_state (cell->state_set, ATK_STATE_SELECTABLE);
- cell->refresh_index = NULL;
-}
-
-static void
-gail_cell_object_finalize (GObject *obj)
-{
- GailCell *cell = GAIL_CELL (obj);
- AtkRelationSet *relation_set;
- AtkRelation *relation;
- GPtrArray *target;
- gpointer target_object;
- gint i;
-
- if (cell->state_set)
- g_object_unref (cell->state_set);
- if (cell->action_list)
- {
- g_list_foreach (cell->action_list, _gail_cell_destroy_action_info, NULL);
- g_list_free (cell->action_list);
- }
- if (cell->action_idle_handler)
- {
- g_source_remove (cell->action_idle_handler);
- cell->action_idle_handler = 0;
- }
- relation_set = atk_object_ref_relation_set (ATK_OBJECT (obj));
- if (ATK_IS_RELATION_SET (relation_set))
- {
- relation = atk_relation_set_get_relation_by_type (relation_set,
- ATK_RELATION_NODE_CHILD_OF);
- if (relation)
- {
- target = atk_relation_get_target (relation);
- for (i = 0; i < target->len; i++)
- {
- target_object = g_ptr_array_index (target, i);
- if (GAIL_IS_CELL (target_object))
- {
- g_object_unref (target_object);
- }
- }
- }
- g_object_unref (relation_set);
- }
- G_OBJECT_CLASS (gail_cell_parent_class)->finalize (obj);
-}
-
-static AtkStateSet *
-gail_cell_ref_state_set (AtkObject *obj)
-{
- GailCell *cell = GAIL_CELL (obj);
- g_assert (cell->state_set);
-
- g_object_ref(cell->state_set);
- return cell->state_set;
-}
-
-gboolean
-gail_cell_add_state (GailCell *cell,
- AtkStateType state_type,
- gboolean emit_signal)
-{
- if (!atk_state_set_contains_state (cell->state_set, state_type))
- {
- gboolean rc;
- AtkObject *parent;
-
- rc = atk_state_set_add_state (cell->state_set, state_type);
- /*
- * The signal should only be generated if the value changed,
- * not when the cell is set up. So states that are set
- * initially should pass FALSE as the emit_signal argument.
- */
-
- if (emit_signal)
- {
- atk_object_notify_state_change (ATK_OBJECT (cell), state_type, TRUE);
- /* If state_type is ATK_STATE_VISIBLE, additional notification */
- if (state_type == ATK_STATE_VISIBLE)
- g_signal_emit_by_name (cell, "visible_data_changed");
- }
-
- /*
- * If the parent is a flyweight container cell, propagate the state
- * change to it also
- */
-
- parent = atk_object_get_parent (ATK_OBJECT (cell));
- if (GAIL_IS_CONTAINER_CELL (parent))
- gail_cell_add_state (GAIL_CELL (parent), state_type, emit_signal);
- return rc;
- }
- else
- return FALSE;
-}
-
-gboolean
-gail_cell_remove_state (GailCell *cell,
- AtkStateType state_type,
- gboolean emit_signal)
-{
- if (atk_state_set_contains_state (cell->state_set, state_type))
- {
- gboolean rc;
- AtkObject *parent;
-
- parent = atk_object_get_parent (ATK_OBJECT (cell));
-
- rc = atk_state_set_remove_state (cell->state_set, state_type);
- /*
- * The signal should only be generated if the value changed,
- * not when the cell is set up. So states that are set
- * initially should pass FALSE as the emit_signal argument.
- */
-
- if (emit_signal)
- {
- atk_object_notify_state_change (ATK_OBJECT (cell), state_type, FALSE);
- /* If state_type is ATK_STATE_VISIBLE, additional notification */
- if (state_type == ATK_STATE_VISIBLE)
- g_signal_emit_by_name (cell, "visible_data_changed");
- }
-
- /*
- * If the parent is a flyweight container cell, propagate the state
- * change to it also
- */
-
- if (GAIL_IS_CONTAINER_CELL (parent))
- gail_cell_remove_state (GAIL_CELL (parent), state_type, emit_signal);
- return rc;
- }
- else
- return FALSE;
-}
-
-static gint
-gail_cell_get_index_in_parent (AtkObject *obj)
-{
- GailCell *cell;
-
- g_assert (GAIL_IS_CELL (obj));
-
- cell = GAIL_CELL (obj);
- if (atk_state_set_contains_state (cell->state_set, ATK_STATE_STALE))
- if (cell->refresh_index)
- {
- cell->refresh_index (cell);
- atk_state_set_remove_state (cell->state_set, ATK_STATE_STALE);
- }
- return cell->index;
-}
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- iface->get_n_actions = gail_cell_action_get_n_actions;
- iface->do_action = gail_cell_action_do_action;
- iface->get_name = gail_cell_action_get_name;
- iface->get_description = gail_cell_action_get_description;
- iface->set_description = gail_cell_action_set_description;
- iface->get_keybinding = gail_cell_action_get_keybinding;
-}
-
-gboolean
-gail_cell_add_action (GailCell *cell,
- const gchar *action_name,
- const gchar *action_description,
- const gchar *action_keybinding,
- ACTION_FUNC action_func)
-{
- ActionInfo *info;
- g_return_val_if_fail (GAIL_IS_CELL (cell), FALSE);
- info = g_new (ActionInfo, 1);
-
- if (action_name != NULL)
- info->name = g_strdup (action_name);
- else
- info->name = NULL;
- if (action_description != NULL)
- info->description = g_strdup (action_description);
- else
- info->description = NULL;
- if (action_keybinding != NULL)
- info->keybinding = g_strdup (action_keybinding);
- else
- info->keybinding = NULL;
- info->do_action_func = action_func;
-
- cell->action_list = g_list_append (cell->action_list, (gpointer) info);
- return TRUE;
-}
-
-gboolean
-gail_cell_remove_action (GailCell *cell,
- gint action_index)
-{
- GList *list_node;
-
- g_return_val_if_fail (GAIL_IS_CELL (cell), FALSE);
- list_node = g_list_nth (cell->action_list, action_index);
- if (!list_node)
- return FALSE;
- _gail_cell_destroy_action_info (list_node->data, NULL);
- cell->action_list = g_list_remove_link (cell->action_list, list_node);
- return TRUE;
-}
-
-
-gboolean
-gail_cell_remove_action_by_name (GailCell *cell,
- const gchar *action_name)
-{
- GList *list_node;
- gboolean action_found= FALSE;
-
- g_return_val_if_fail (GAIL_IS_CELL (cell), FALSE);
- for (list_node = cell->action_list; list_node && !action_found;
- list_node = list_node->next)
- {
- if (!strcmp (((ActionInfo *)(list_node->data))->name, action_name))
- {
- action_found = TRUE;
- break;
- }
- }
- if (!action_found)
- return FALSE;
- _gail_cell_destroy_action_info (list_node->data, NULL);
- cell->action_list = g_list_remove_link (cell->action_list, list_node);
- return TRUE;
-}
-
-static ActionInfo *
-_gail_cell_get_action_info (GailCell *cell,
- gint index)
-{
- GList *list_node;
-
- g_return_val_if_fail (GAIL_IS_CELL (cell), NULL);
- if (cell->action_list == NULL)
- return NULL;
- list_node = g_list_nth (cell->action_list, index);
- if (!list_node)
- return NULL;
- return (ActionInfo *) (list_node->data);
-}
-
-
-static void
-_gail_cell_destroy_action_info (gpointer action_info,
- gpointer user_data)
-{
- ActionInfo *info = (ActionInfo *)action_info;
- g_assert (info != NULL);
- g_free (info->name);
- g_free (info->description);
- g_free (info->keybinding);
- g_free (info);
-}
-static gint
-gail_cell_action_get_n_actions (AtkAction *action)
-{
- GailCell *cell = GAIL_CELL(action);
- if (cell->action_list != NULL)
- return g_list_length (cell->action_list);
- else
- return 0;
-}
-
-static const gchar *
-gail_cell_action_get_name (AtkAction *action,
- gint index)
-{
- GailCell *cell = GAIL_CELL(action);
- ActionInfo *info = _gail_cell_get_action_info (cell, index);
-
- if (info == NULL)
- return NULL;
- return info->name;
-}
-
-static const gchar *
-gail_cell_action_get_description (AtkAction *action,
- gint index)
-{
- GailCell *cell = GAIL_CELL(action);
- ActionInfo *info = _gail_cell_get_action_info (cell, index);
-
- if (info == NULL)
- return NULL;
- return info->description;
-}
-
-static gboolean
-gail_cell_action_set_description (AtkAction *action,
- gint index,
- const gchar *desc)
-{
- GailCell *cell = GAIL_CELL(action);
- ActionInfo *info = _gail_cell_get_action_info (cell, index);
-
- if (info == NULL)
- return FALSE;
- g_free (info->description);
- info->description = g_strdup (desc);
- return TRUE;
-}
-
-static const gchar *
-gail_cell_action_get_keybinding (AtkAction *action,
- gint index)
-{
- GailCell *cell = GAIL_CELL(action);
- ActionInfo *info = _gail_cell_get_action_info (cell, index);
- if (info == NULL)
- return NULL;
- return info->keybinding;
-}
-
-static gboolean
-gail_cell_action_do_action (AtkAction *action,
- gint index)
-{
- GailCell *cell = GAIL_CELL(action);
- ActionInfo *info = _gail_cell_get_action_info (cell, index);
- if (info == NULL)
- return FALSE;
- if (info->do_action_func == NULL)
- return FALSE;
- if (cell->action_idle_handler)
- return FALSE;
- cell->action_func = info->do_action_func;
- cell->action_idle_handler = gdk_threads_add_idle (idle_do_action, cell);
- return TRUE;
-}
-
-static gboolean
-idle_do_action (gpointer data)
-{
- GailCell *cell;
-
- cell = GAIL_CELL (data);
- cell->action_idle_handler = 0;
- cell->action_func (cell);
-
- return FALSE;
-}
-
-static void
-atk_component_interface_init (AtkComponentIface *iface)
-{
- iface->get_extents = gail_cell_get_extents;
- iface->grab_focus = gail_cell_grab_focus;
-}
-
-static void
-gail_cell_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type)
-{
- GailCell *gailcell;
- AtkObject *cell_parent;
-
- g_assert (GAIL_IS_CELL (component));
-
- gailcell = GAIL_CELL (component);
-
- cell_parent = gtk_widget_get_accessible (gailcell->widget);
-
- gail_cell_parent_get_cell_extents (GAIL_CELL_PARENT (cell_parent),
- gailcell, x, y, width, height, coord_type);
-}
-
-static gboolean
-gail_cell_grab_focus (AtkComponent *component)
-{
- GailCell *gailcell;
- AtkObject *cell_parent;
-
- g_assert (GAIL_IS_CELL (component));
-
- gailcell = GAIL_CELL (component);
-
- cell_parent = gtk_widget_get_accessible (gailcell->widget);
-
- return gail_cell_parent_grab_focus (GAIL_CELL_PARENT (cell_parent),
- gailcell);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_CELL_H__
-#define __GAIL_CELL_H__
-
-#include <atk/atk.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_CELL (gail_cell_get_type ())
-#define GAIL_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CELL, GailCell))
-#define GAIL_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CELL, GailCellClass))
-#define GAIL_IS_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CELL))
-#define GAIL_IS_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CELL))
-#define GAIL_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CELL, GailCellClass))
-
-typedef struct _GailCell GailCell;
-typedef struct _GailCellClass GailCellClass;
-typedef struct _ActionInfo ActionInfo;
-typedef void (*ACTION_FUNC) (GailCell *cell);
-
-struct _GailCell
-{
- AtkObject parent;
-
- GtkWidget *widget;
- /*
- * This cached value is used only by atk_object_get_index_in_parent()
- * which updates the value when it is stale.
- */
- gint index;
- AtkStateSet *state_set;
- GList *action_list;
- void (*refresh_index) (GailCell *cell);
- gint action_idle_handler;
- ACTION_FUNC action_func;
-};
-
-GType gail_cell_get_type (void);
-
-struct _GailCellClass
-{
- AtkObjectClass parent_class;
-};
-
-struct _ActionInfo {
- gchar *name;
- gchar *description;
- gchar *keybinding;
- ACTION_FUNC do_action_func;
-};
-
-void gail_cell_initialise (GailCell *cell,
- GtkWidget *widget,
- AtkObject *parent,
- gint index);
-
-gboolean gail_cell_add_state (GailCell *cell,
- AtkStateType state_type,
- gboolean emit_signal);
-
-gboolean gail_cell_remove_state (GailCell *cell,
- AtkStateType state_type,
- gboolean emit_signal);
-
-gboolean gail_cell_add_action (GailCell *cell,
- const gchar *action_name,
- const gchar *action_description,
- const gchar *action_keybinding,
- ACTION_FUNC action_func);
-
-gboolean gail_cell_remove_action (GailCell *cell,
- gint action_id);
-
-gboolean gail_cell_remove_action_by_name (GailCell *cell,
- const gchar *action_name);
-
-G_END_DECLS
-
-#endif /* __GAIL_CELL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
-
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailcellparent.h"
-
-GType
-gail_cell_parent_get_type (void)
-{
- static volatile gsize g_define_type_id__volatile = 0;
-
- if (g_once_init_enter (&g_define_type_id__volatile))
- {
- GType g_define_type_id =
- g_type_register_static_simple (G_TYPE_INTERFACE,
- "GailCellParent",
- sizeof (GailCellParentIface),
- NULL,
- 0,
- NULL,
- 0);
-
- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
- }
-
- return g_define_type_id__volatile;
-}
-
-/**
- * gail_cell_parent_get_cell_extents:
- * @parent: a #GObject instance that implements GailCellParentIface
- * @cell: a #GailCell whose extents is required
- * @x: address of #gint to put x coordinate
- * @y: address of #gint to put y coordinate
- * @width: address of #gint to put width
- * @height: address of #gint to put height
- * @coord_type: specifies whether the coordinates are relative to the screen
- * or to the components top level window
- *
- * Gets the rectangle which gives the extent of the @cell.
- *
- **/
-void
-gail_cell_parent_get_cell_extents (GailCellParent *parent,
- GailCell *cell,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type)
-{
- GailCellParentIface *iface;
-
- g_return_if_fail (GAIL_IS_CELL_PARENT (parent));
-
- iface = GAIL_CELL_PARENT_GET_IFACE (parent);
-
- if (iface->get_cell_extents)
- (iface->get_cell_extents) (parent, cell, x, y, width, height, coord_type);
-}
-
-/**
- * gail_cell_parent_get_cell_area:
- * @parent: a #GObject instance that implements GailCellParentIface
- * @cell: a #GailCell whose area is required
- * @cell_rect: address of #GdkRectangle to put the cell area
- *
- * Gets the cell area of the @cell.
- *
- **/
-void
-gail_cell_parent_get_cell_area (GailCellParent *parent,
- GailCell *cell,
- GdkRectangle *cell_rect)
-{
- GailCellParentIface *iface;
-
- g_return_if_fail (GAIL_IS_CELL_PARENT (parent));
- g_return_if_fail (cell_rect);
-
- iface = GAIL_CELL_PARENT_GET_IFACE (parent);
-
- if (iface->get_cell_area)
- (iface->get_cell_area) (parent, cell, cell_rect);
-}
-/**
- * gail_cell_parent_grab_focus:
- * @parent: a #GObject instance that implements GailCellParentIface
- * @cell: a #GailCell whose area is required
- *
- * Puts focus in the specified cell.
- *
- **/
-gboolean
-gail_cell_parent_grab_focus (GailCellParent *parent,
- GailCell *cell)
-{
- GailCellParentIface *iface;
-
- g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), FALSE);
-
- iface = GAIL_CELL_PARENT_GET_IFACE (parent);
-
- if (iface->grab_focus)
- return (iface->grab_focus) (parent, cell);
- else
- return FALSE;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- *
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_CELL_PARENT_H__
-#define __GAIL_CELL_PARENT_H__
-
-#include <atk/atk.h>
-#include "gailcell.h"
-
-G_BEGIN_DECLS
-
-/*
- * The GailCellParent interface should be supported by any object which
- * contains children which are flyweights, i.e. do not have corresponding
- * widgets and the children need help from their parent to provide
- * functionality. One example is GailTreeView where the children GailCell
- * need help from the GailTreeView in order to implement
- * atk_component_get_extents
- */
-
-#define GAIL_TYPE_CELL_PARENT (gail_cell_parent_get_type ())
-#define GAIL_IS_CELL_PARENT(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CELL_PARENT)
-#define GAIL_CELL_PARENT(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CELL_PARENT, GailCellParent)
-#define GAIL_CELL_PARENT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GAIL_TYPE_CELL_PARENT, GailCellParentIface))
-
-#ifndef _TYPEDEF_GAIL_CELL_PARENT_
-#define _TYPEDEF_GAIL_CELL_PARENT_
-typedef struct _GailCellParent GailCellParent;
-#endif
-typedef struct _GailCellParentIface GailCellParentIface;
-
-struct _GailCellParentIface
-{
- GTypeInterface parent;
- void ( *get_cell_extents) (GailCellParent *parent,
- GailCell *cell,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type);
- void ( *get_cell_area) (GailCellParent *parent,
- GailCell *cell,
- GdkRectangle *cell_rect);
- gboolean ( *grab_focus) (GailCellParent *parent,
- GailCell *cell);
-};
-
-GType gail_cell_parent_get_type (void);
-
-void gail_cell_parent_get_cell_extents (GailCellParent *parent,
- GailCell *cell,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type
-);
-void gail_cell_parent_get_cell_area (GailCellParent *parent,
- GailCell *cell,
- GdkRectangle *cell_rect);
-gboolean gail_cell_parent_grab_focus (GailCellParent *parent,
- GailCell *cell);
-
-G_END_DECLS
-
-#endif /* __GAIL_CELL_PARENT_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include "gailcheckmenuitem.h"
-#include "gailchecksubmenuitem.h"
-
-static void gail_check_menu_item_class_init (GailCheckMenuItemClass *klass);
-
-static void gail_check_menu_item_init (GailCheckMenuItem *item);
-
-static void gail_check_menu_item_toggled_gtk (GtkWidget *widget);
-
-static void gail_check_menu_item_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-
-static void gail_check_menu_item_real_initialize (AtkObject *obj,
- gpointer data);
-
-static AtkStateSet* gail_check_menu_item_ref_state_set (AtkObject *accessible);
-
-G_DEFINE_TYPE (GailCheckMenuItem, gail_check_menu_item, GAIL_TYPE_MENU_ITEM)
-
-static void
-gail_check_menu_item_class_init (GailCheckMenuItemClass *klass)
-{
- GailWidgetClass *widget_class;
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- widget_class = (GailWidgetClass*)klass;
- widget_class->notify_gtk = gail_check_menu_item_real_notify_gtk;
-
- class->ref_state_set = gail_check_menu_item_ref_state_set;
- class->initialize = gail_check_menu_item_real_initialize;
-}
-
-static void
-gail_check_menu_item_init (GailCheckMenuItem *item)
-{
-}
-
-AtkObject*
-gail_check_menu_item_new (GtkWidget *widget)
-{
- GObject *object;
- AtkObject *accessible;
-
- g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (widget), NULL);
-
- if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)))
- return gail_check_sub_menu_item_new (widget);
-
- object = g_object_new (GAIL_TYPE_CHECK_MENU_ITEM, NULL);
-
- accessible = ATK_OBJECT (object);
- atk_object_initialize (accessible, widget);
-
- return accessible;
-}
-
-static void
-gail_check_menu_item_real_initialize (AtkObject *obj,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_check_menu_item_parent_class)->initialize (obj, data);
-
- g_signal_connect (data,
- "toggled",
- G_CALLBACK (gail_check_menu_item_toggled_gtk),
- NULL);
-
- obj->role = ATK_ROLE_CHECK_MENU_ITEM;
-}
-
-static void
-gail_check_menu_item_toggled_gtk (GtkWidget *widget)
-{
- AtkObject *accessible;
- GtkCheckMenuItem *check_menu_item;
-
- check_menu_item = GTK_CHECK_MENU_ITEM (widget);
-
- accessible = gtk_widget_get_accessible (widget);
- atk_object_notify_state_change (accessible, ATK_STATE_CHECKED,
- gtk_check_menu_item_get_active (check_menu_item));
-}
-
-static AtkStateSet*
-gail_check_menu_item_ref_state_set (AtkObject *accessible)
-{
- AtkStateSet *state_set;
- GtkCheckMenuItem *check_menu_item;
- GtkWidget *widget;
-
- state_set = ATK_OBJECT_CLASS (gail_check_menu_item_parent_class)->ref_state_set (accessible);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- return state_set;
-
- check_menu_item = GTK_CHECK_MENU_ITEM (widget);
-
- if (gtk_check_menu_item_get_active (check_menu_item))
- atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
-
- if (gtk_check_menu_item_get_inconsistent (check_menu_item))
- {
- atk_state_set_remove_state (state_set, ATK_STATE_ENABLED);
- atk_state_set_add_state (state_set, ATK_STATE_INDETERMINATE);
- }
-
- return state_set;
-}
-
-static void
-gail_check_menu_item_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (obj);
- AtkObject *atk_obj;
- gboolean sensitive;
- gboolean inconsistent;
-
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (check_menu_item));
- sensitive = gtk_widget_get_sensitive (GTK_WIDGET (check_menu_item));
- inconsistent = gtk_check_menu_item_get_inconsistent (check_menu_item);
-
- if (strcmp (pspec->name, "inconsistent") == 0)
- {
- atk_object_notify_state_change (atk_obj, ATK_STATE_INDETERMINATE, inconsistent);
- atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
- }
- else if (strcmp (pspec->name, "sensitive") == 0)
- {
- /* Need to override gailwidget behavior of notifying for ENABLED */
- atk_object_notify_state_change (atk_obj, ATK_STATE_SENSITIVE, sensitive);
- atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
- }
- else
- GAIL_WIDGET_CLASS (gail_check_menu_item_parent_class)->notify_gtk (obj, pspec);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_CHECK_MENU_ITEM_H__
-#define __GAIL_CHECK_MENU_ITEM_H__
-
-#include "gailmenuitem.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_CHECK_MENU_ITEM (gail_check_menu_item_get_type ())
-#define GAIL_CHECK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CHECK_MENU_ITEM, GailCheckMenuItem))
-#define GAIL_CHECK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CHECK_MENU_ITEM, GailCheckMenuItemClass))
-#define GAIL_IS_CHECK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CHECK_MENU_ITEM))
-#define GAIL_IS_CHECK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CHECK_MENU_ITEM))
-#define GAIL_CHECK_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CHECK_MENU_ITEM, GailCheckMenuItemClass))
-
-typedef struct _GailCheckMenuItem GailCheckMenuItem;
-typedef struct _GailCheckMenuItemClass GailCheckMenuItemClass;
-
-struct _GailCheckMenuItem
-{
- GailMenuItem parent;
-};
-
-GType gail_check_menu_item_get_type (void);
-
-struct _GailCheckMenuItemClass
-{
- GailMenuItemClass parent_class;
-};
-
-AtkObject* gail_check_menu_item_new (GtkWidget *widget);
-
-G_END_DECLS
-
-#endif /* __GAIL_CHECK_MENU_ITEM_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailchecksubmenuitem.h"
-
-static void gail_check_sub_menu_item_class_init (GailCheckSubMenuItemClass *klass);
-
-static void gail_check_sub_menu_item_init (GailCheckSubMenuItem *item);
-
-static void gail_check_sub_menu_item_toggled_gtk (GtkWidget *widget);
-
-static void gail_check_sub_menu_item_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-
-static void gail_check_sub_menu_item_real_initialize (AtkObject *obj,
- gpointer data);
-
-static AtkStateSet* gail_check_sub_menu_item_ref_state_set (AtkObject *accessible);
-
-G_DEFINE_TYPE (GailCheckSubMenuItem, gail_check_sub_menu_item, GAIL_TYPE_SUB_MENU_ITEM)
-
-static void
-gail_check_sub_menu_item_class_init (GailCheckSubMenuItemClass *klass)
-{
- GailWidgetClass *widget_class;
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- widget_class = (GailWidgetClass*)klass;
- widget_class->notify_gtk = gail_check_sub_menu_item_real_notify_gtk;
-
- class->ref_state_set = gail_check_sub_menu_item_ref_state_set;
- class->initialize = gail_check_sub_menu_item_real_initialize;
-}
-
-static void
-gail_check_sub_menu_item_init (GailCheckSubMenuItem *item)
-{
-}
-
-AtkObject*
-gail_check_sub_menu_item_new (GtkWidget *widget)
-{
- GObject *object;
- AtkObject *accessible;
-
- g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (widget), NULL);
-
- object = g_object_new (GAIL_TYPE_CHECK_SUB_MENU_ITEM, NULL);
-
- accessible = ATK_OBJECT (object);
- atk_object_initialize (accessible, widget);
-
- return accessible;
-}
-
-static void
-gail_check_sub_menu_item_real_initialize (AtkObject *obj,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_check_sub_menu_item_parent_class)->initialize (obj, data);
-
- g_signal_connect (data,
- "toggled",
- G_CALLBACK (gail_check_sub_menu_item_toggled_gtk),
- NULL);
-
- obj->role = ATK_ROLE_CHECK_MENU_ITEM;
-}
-
-static void
-gail_check_sub_menu_item_toggled_gtk (GtkWidget *widget)
-{
- AtkObject *accessible;
- GtkCheckMenuItem *check_menu_item;
-
- check_menu_item = GTK_CHECK_MENU_ITEM (widget);
-
- accessible = gtk_widget_get_accessible (widget);
- atk_object_notify_state_change (accessible, ATK_STATE_CHECKED,
- gtk_check_menu_item_get_active (check_menu_item));
-}
-
-static AtkStateSet*
-gail_check_sub_menu_item_ref_state_set (AtkObject *accessible)
-{
- AtkStateSet *state_set;
- GtkCheckMenuItem *check_menu_item;
- GtkWidget *widget;
-
- state_set = ATK_OBJECT_CLASS (gail_check_sub_menu_item_parent_class)->ref_state_set (accessible);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- return state_set;
-
- check_menu_item = GTK_CHECK_MENU_ITEM (widget);
-
- if (gtk_check_menu_item_get_active (check_menu_item))
- atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
-
- if (gtk_check_menu_item_get_inconsistent (check_menu_item))
- {
- atk_state_set_remove_state (state_set, ATK_STATE_ENABLED);
- atk_state_set_add_state (state_set, ATK_STATE_INDETERMINATE);
- }
-
- return state_set;
-}
-
-static void
-gail_check_sub_menu_item_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (obj);
- AtkObject *atk_obj;
- gboolean sensitive;
- gboolean inconsistent;
-
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (check_menu_item));
- sensitive = gtk_widget_get_sensitive (GTK_WIDGET (check_menu_item));
- inconsistent = gtk_check_menu_item_get_inconsistent (check_menu_item);
-
- if (strcmp (pspec->name, "inconsistent") == 0)
- {
- atk_object_notify_state_change (atk_obj, ATK_STATE_INDETERMINATE, inconsistent);
- atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
- }
- else if (strcmp (pspec->name, "sensitive") == 0)
- {
- /* Need to override gailwidget behavior of notifying for ENABLED */
- atk_object_notify_state_change (atk_obj, ATK_STATE_SENSITIVE, sensitive);
- atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
- }
- else
- GAIL_WIDGET_CLASS (gail_check_sub_menu_item_parent_class)->notify_gtk (obj, pspec);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_CHECK_SUB_MENU_ITEM_H__
-#define __GAIL_CHECK_SUB_MENU_ITEM_H__
-
-#include "gailsubmenuitem.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_CHECK_SUB_MENU_ITEM (gail_check_sub_menu_item_get_type ())
-#define GAIL_CHECK_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CHECK_SUB_MENU_ITEM, GailCheckSubMenuItem))
-#define GAIL_CHECK_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CHECK_SUB_MENU_ITEM, GailCheckSubMenuItemClass))
-#define GAIL_IS_CHECK_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CHECK_SUB_MENU_ITEM))
-#define GAIL_IS_CHECK_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CHECK_SUB_MENU_ITEM))
-#define GAIL_CHECK_SUB_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CHECK_SUB_MENU_ITEM, GailCheckSubMenuItemClass))
-
-typedef struct _GailCheckSubMenuItem GailCheckSubMenuItem;
-typedef struct _GailCheckSubMenuItemClass GailCheckSubMenuItemClass;
-
-struct _GailCheckSubMenuItem
-{
- GailSubMenuItem parent;
-};
-
-GType gail_check_sub_menu_item_get_type (void);
-
-struct _GailCheckSubMenuItemClass
-{
- GailSubMenuItemClass parent_class;
-};
-
-AtkObject* gail_check_sub_menu_item_new (GtkWidget *widget);
-
-G_END_DECLS
-
-#endif /* __GAIL_CHECK_SUB_MENU_ITEM_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2004 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "gailcombobox.h"
-
-static void gail_combo_box_class_init (GailComboBoxClass *klass);
-static void gail_combo_box_init (GailComboBox *combo_box);
-static void gail_combo_box_real_initialize (AtkObject *obj,
- gpointer data);
-
-static void gail_combo_box_changed_gtk (GtkWidget *widget);
-
-static const gchar* gail_combo_box_get_name (AtkObject *obj);
-static gint gail_combo_box_get_n_children (AtkObject *obj);
-static AtkObject* gail_combo_box_ref_child (AtkObject *obj,
- gint i);
-static void gail_combo_box_finalize (GObject *object);
-static void atk_action_interface_init (AtkActionIface *iface);
-
-static gboolean gail_combo_box_do_action (AtkAction *action,
- gint i);
-static gboolean idle_do_action (gpointer data);
-static gint gail_combo_box_get_n_actions (AtkAction *action);
-static const gchar* gail_combo_box_get_description(AtkAction *action,
- gint i);
-static const gchar* gail_combo_box_get_keybinding (AtkAction *action,
- gint i);
-static const gchar* gail_combo_box_action_get_name(AtkAction *action,
- gint i);
-static gboolean gail_combo_box_set_description(AtkAction *action,
- gint i,
- const gchar *desc);
-static void atk_selection_interface_init (AtkSelectionIface *iface);
-static gboolean gail_combo_box_add_selection (AtkSelection *selection,
- gint i);
-static gboolean gail_combo_box_clear_selection (AtkSelection *selection);
-static AtkObject* gail_combo_box_ref_selection (AtkSelection *selection,
- gint i);
-static gint gail_combo_box_get_selection_count (AtkSelection *selection);
-static gboolean gail_combo_box_is_child_selected (AtkSelection *selection,
- gint i);
-static gboolean gail_combo_box_remove_selection (AtkSelection *selection,
- gint i);
-
-G_DEFINE_TYPE_WITH_CODE (GailComboBox, gail_combo_box, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
-
-static void
-gail_combo_box_class_init (GailComboBoxClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- gobject_class->finalize = gail_combo_box_finalize;
-
- class->get_name = gail_combo_box_get_name;
- class->get_n_children = gail_combo_box_get_n_children;
- class->ref_child = gail_combo_box_ref_child;
- class->initialize = gail_combo_box_real_initialize;
-}
-
-static void
-gail_combo_box_init (GailComboBox *combo_box)
-{
- combo_box->press_description = NULL;
- combo_box->press_keybinding = NULL;
- combo_box->old_selection = -1;
- combo_box->name = NULL;
- combo_box->popup_set = FALSE;
-}
-
-static void
-gail_combo_box_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkComboBox *combo_box;
- GailComboBox *gail_combo_box;
- AtkObject *popup;
-
- ATK_OBJECT_CLASS (gail_combo_box_parent_class)->initialize (obj, data);
-
- combo_box = GTK_COMBO_BOX (data);
-
- gail_combo_box = GAIL_COMBO_BOX (obj);
-
- g_signal_connect (combo_box,
- "changed",
- G_CALLBACK (gail_combo_box_changed_gtk),
- NULL);
- gail_combo_box->old_selection = gtk_combo_box_get_active (combo_box);
-
- popup = gtk_combo_box_get_popup_accessible (combo_box);
- if (popup)
- {
- atk_object_set_parent (popup, obj);
- gail_combo_box->popup_set = TRUE;
- }
- if (gtk_combo_box_get_has_entry (combo_box))
- atk_object_set_parent (gtk_widget_get_accessible (gtk_bin_get_child (GTK_BIN (combo_box))), obj);
-
- obj->role = ATK_ROLE_COMBO_BOX;
-}
-
-static void
-gail_combo_box_changed_gtk (GtkWidget *widget)
-{
- GtkComboBox *combo_box;
- AtkObject *obj;
- GailComboBox *gail_combo_box;
- gint index;
-
- combo_box = GTK_COMBO_BOX (widget);
-
- index = gtk_combo_box_get_active (combo_box);
- obj = gtk_widget_get_accessible (widget);
- gail_combo_box = GAIL_COMBO_BOX (obj);
- if (gail_combo_box->old_selection != index)
- {
- gail_combo_box->old_selection = index;
- g_object_notify (G_OBJECT (obj), "accessible-name");
- g_signal_emit_by_name (obj, "selection_changed");
- }
-}
-
-static const gchar*
-gail_combo_box_get_name (AtkObject *obj)
-{
- GtkWidget *widget;
- GtkComboBox *combo_box;
- GailComboBox *gail_combo_box;
- GtkTreeIter iter;
- const gchar *name;
- GtkTreeModel *model;
- gint n_columns;
- gint i;
-
- g_return_val_if_fail (GAIL_IS_COMBO_BOX (obj), NULL);
-
- name = ATK_OBJECT_CLASS (gail_combo_box_parent_class)->get_name (obj);
- if (name)
- return name;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- combo_box = GTK_COMBO_BOX (widget);
- gail_combo_box = GAIL_COMBO_BOX (obj);
- if (gtk_combo_box_get_active_iter (combo_box, &iter))
- {
- model = gtk_combo_box_get_model (combo_box);
- n_columns = gtk_tree_model_get_n_columns (model);
- for (i = 0; i < n_columns; i++)
- {
- GValue value = { 0, };
-
- gtk_tree_model_get_value (model, &iter, i, &value);
- if (G_VALUE_HOLDS_STRING (&value))
- {
- if (gail_combo_box->name) g_free (gail_combo_box->name);
- gail_combo_box->name = g_strdup ((gchar *)
- g_value_get_string (&value));
- g_value_unset (&value);
- break;
- }
- else
- g_value_unset (&value);
- }
- }
- return gail_combo_box->name;
-}
-
-/*
- * The children of a GailComboBox are the list of items and the entry field
- * if it is editable.
- */
-static gint
-gail_combo_box_get_n_children (AtkObject* obj)
-{
- gint n_children = 0;
- GtkWidget *widget;
-
- g_return_val_if_fail (GAIL_IS_COMBO_BOX (obj), 0);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return 0;
-
- n_children++;
- if (gtk_combo_box_get_has_entry (GTK_COMBO_BOX (widget)))
- n_children ++;
-
- return n_children;
-}
-
-static AtkObject*
-gail_combo_box_ref_child (AtkObject *obj,
- gint i)
-{
- GtkWidget *widget;
- AtkObject *child;
- GailComboBox *box;
-
- g_return_val_if_fail (GAIL_IS_COMBO_BOX (obj), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- if (i == 0)
- {
- child = gtk_combo_box_get_popup_accessible (GTK_COMBO_BOX (widget));
- box = GAIL_COMBO_BOX (obj);
- if (box->popup_set == FALSE)
- {
- atk_object_set_parent (child, obj);
- box->popup_set = TRUE;
- }
- }
- else if (i == 1 && gtk_combo_box_get_has_entry (GTK_COMBO_BOX (widget)))
- {
- child = gtk_widget_get_accessible (gtk_bin_get_child (GTK_BIN (widget)));
- }
- else
- {
- return NULL;
- }
- return g_object_ref (child);
-}
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- iface->do_action = gail_combo_box_do_action;
- iface->get_n_actions = gail_combo_box_get_n_actions;
- iface->get_description = gail_combo_box_get_description;
- iface->get_keybinding = gail_combo_box_get_keybinding;
- iface->get_name = gail_combo_box_action_get_name;
- iface->set_description = gail_combo_box_set_description;
-}
-
-static gboolean
-gail_combo_box_do_action (AtkAction *action,
- gint i)
-{
- GailComboBox *combo_box;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- if (!gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- combo_box = GAIL_COMBO_BOX (action);
- if (i == 0)
- {
- if (combo_box->action_idle_handler)
- return FALSE;
-
- combo_box->action_idle_handler = gdk_threads_add_idle (idle_do_action, combo_box);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gboolean
-idle_do_action (gpointer data)
-{
- GtkComboBox *combo_box;
- GtkWidget *widget;
- GailComboBox *gail_combo_box;
- AtkObject *popup;
- gboolean do_popup;
-
- gail_combo_box = GAIL_COMBO_BOX (data);
- gail_combo_box->action_idle_handler = 0;
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gail_combo_box));
-
- if (widget == NULL || /* State is defunct */
- !gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- combo_box = GTK_COMBO_BOX (widget);
-
- popup = gtk_combo_box_get_popup_accessible (combo_box);
- do_popup = !gtk_widget_get_mapped (gtk_accessible_get_widget (GTK_ACCESSIBLE (popup)));
- if (do_popup)
- gtk_combo_box_popup (combo_box);
- else
- gtk_combo_box_popdown (combo_box);
-
- return FALSE;
-}
-
-static gint
-gail_combo_box_get_n_actions (AtkAction *action)
-{
- /*
- * The default behavior of a combo_box box is to have one action -
- */
- return 1;
-}
-
-static const gchar*
-gail_combo_box_get_description (AtkAction *action,
- gint i)
-{
- if (i == 0)
- {
- GailComboBox *combo_box;
-
- combo_box = GAIL_COMBO_BOX (action);
- return combo_box->press_description;
- }
- else
- return NULL;
-}
-
-static const gchar*
-gail_combo_box_get_keybinding (AtkAction *action,
- gint i)
-{
- GailComboBox *combo_box;
- gchar *return_value = NULL;
- switch (i)
- {
- case 0:
- {
- GtkWidget *widget;
- GtkWidget *label;
- AtkRelationSet *set;
- AtkRelation *relation;
- GPtrArray *target;
- gpointer target_object;
- guint key_val;
-
- combo_box = GAIL_COMBO_BOX (action);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (combo_box));
- if (widget == NULL)
- return NULL;
- set = atk_object_ref_relation_set (ATK_OBJECT (action));
- if (!set)
- return NULL;
- label = NULL;
- relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
- if (relation)
- {
- target = atk_relation_get_target (relation);
- target_object = g_ptr_array_index (target, 0);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
- }
- g_object_unref (set);
- if (GTK_IS_LABEL (label))
- {
- key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
- if (key_val != GDK_KEY_VoidSymbol)
- return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
- }
- g_free (combo_box->press_keybinding);
- combo_box->press_keybinding = return_value;
- break;
- }
- default:
- break;
- }
- return return_value;
-}
-
-
-static const gchar*
-gail_combo_box_action_get_name (AtkAction *action,
- gint i)
-{
- if (i == 0)
- return "press";
- else
- return NULL;
-}
-
-static gboolean
-gail_combo_box_set_description (AtkAction *action,
- gint i,
- const gchar *desc)
-{
- if (i == 0)
- {
- GailComboBox *combo_box;
-
- combo_box = GAIL_COMBO_BOX (action);
- g_free (combo_box->press_description);
- combo_box->press_description = g_strdup (desc);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static void
-atk_selection_interface_init (AtkSelectionIface *iface)
-{
- iface->add_selection = gail_combo_box_add_selection;
- iface->clear_selection = gail_combo_box_clear_selection;
- iface->ref_selection = gail_combo_box_ref_selection;
- iface->get_selection_count = gail_combo_box_get_selection_count;
- iface->is_child_selected = gail_combo_box_is_child_selected;
- iface->remove_selection = gail_combo_box_remove_selection;
- /*
- * select_all_selection does not make sense for a combo_box
- * so no implementation is provided.
- */
-}
-
-static gboolean
-gail_combo_box_add_selection (AtkSelection *selection,
- gint i)
-{
- GtkComboBox *combo_box;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- combo_box = GTK_COMBO_BOX (widget);
-
- gtk_combo_box_set_active (combo_box, i);
- return TRUE;
-}
-
-static gboolean
-gail_combo_box_clear_selection (AtkSelection *selection)
-{
- GtkComboBox *combo_box;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- combo_box = GTK_COMBO_BOX (widget);
-
- gtk_combo_box_set_active (combo_box, -1);
- return TRUE;
-}
-
-static AtkObject*
-gail_combo_box_ref_selection (AtkSelection *selection,
- gint i)
-{
- GtkComboBox *combo_box;
- GtkWidget *widget;
- AtkObject *obj;
- gint index;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- combo_box = GTK_COMBO_BOX (widget);
-
- /*
- * A combo_box box can have only one selection.
- */
- if (i != 0)
- return NULL;
-
- obj = gtk_combo_box_get_popup_accessible (combo_box);
- index = gtk_combo_box_get_active (combo_box);
- return atk_object_ref_accessible_child (obj, index);
-}
-
-static gint
-gail_combo_box_get_selection_count (AtkSelection *selection)
-{
- GtkComboBox *combo_box;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return 0;
-
- combo_box = GTK_COMBO_BOX (widget);
-
- return (gtk_combo_box_get_active (combo_box) == -1) ? 0 : 1;
-}
-
-static gboolean
-gail_combo_box_is_child_selected (AtkSelection *selection,
- gint i)
-{
- GtkComboBox *combo_box;
- gint j;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- combo_box = GTK_COMBO_BOX (widget);
-
- j = gtk_combo_box_get_active (combo_box);
-
- return (j == i);
-}
-
-static gboolean
-gail_combo_box_remove_selection (AtkSelection *selection,
- gint i)
-{
- if (atk_selection_is_child_selected (selection, i))
- atk_selection_clear_selection (selection);
-
- return TRUE;
-}
-
-static void
-gail_combo_box_finalize (GObject *object)
-{
- GailComboBox *combo_box = GAIL_COMBO_BOX (object);
-
- g_free (combo_box->press_description);
- g_free (combo_box->press_keybinding);
- g_free (combo_box->name);
- if (combo_box->action_idle_handler)
- {
- g_source_remove (combo_box->action_idle_handler);
- combo_box->action_idle_handler = 0;
- }
- G_OBJECT_CLASS (gail_combo_box_parent_class)->finalize (object);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2004 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_COMBO_BOX_H__
-#define __GAIL_COMBO_BOX_H__
-
-#include "gailcontainer.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_COMBO_BOX (gail_combo_box_get_type ())
-#define GAIL_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_COMBO_BOX, GailComboBox))
-#define GAIL_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_COMBO_BOX, GailComboBoxClass))
-#define GAIL_IS_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_COMBO_BOX))
-#define GAIL_IS_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_COMBO_BOX))
-#define GAIL_COMBO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_COMBO_BOX, GailComboBoxClass))
-
-typedef struct _GailComboBox GailComboBox;
-typedef struct _GailComboBoxClass GailComboBoxClass;
-
-struct _GailComboBox
-{
- GailContainer parent;
-
- gchar *press_keybinding;
- gchar *press_description;
- guint action_idle_handler;
-
- gchar *name;
- gint old_selection;
- gboolean popup_set;
-};
-
-GType gail_combo_box_get_type (void);
-
-struct _GailComboBoxClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_COMBO_BOX_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailcontainer.h"
-
-static void gail_container_class_init (GailContainerClass *klass);
-static void gail_container_init (GailContainer *container);
-
-static gint gail_container_get_n_children (AtkObject *obj);
-static AtkObject* gail_container_ref_child (AtkObject *obj,
- gint i);
-static gint gail_container_add_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data);
-static gint gail_container_remove_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data);
-static gint gail_container_real_add_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data);
-static gint gail_container_real_remove_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data);
-
-static void gail_container_real_initialize (AtkObject *obj,
- gpointer data);
-
-static void gail_container_finalize (GObject *object);
-
-G_DEFINE_TYPE (GailContainer, gail_container, GAIL_TYPE_WIDGET)
-
-static void
-gail_container_class_init (GailContainerClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- gobject_class->finalize = gail_container_finalize;
-
- class->get_n_children = gail_container_get_n_children;
- class->ref_child = gail_container_ref_child;
- class->initialize = gail_container_real_initialize;
-
- klass->add_gtk = gail_container_real_add_gtk;
- klass->remove_gtk = gail_container_real_remove_gtk;
-}
-
-static void
-gail_container_init (GailContainer *container)
-{
- container->children = NULL;
-}
-
-static gint
-gail_container_get_n_children (AtkObject* obj)
-{
- GtkWidget *widget;
- GList *children;
- gint count = 0;
-
- g_return_val_if_fail (GAIL_IS_CONTAINER (obj), count);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return 0;
-
- children = gtk_container_get_children (GTK_CONTAINER(widget));
- count = g_list_length (children);
- g_list_free (children);
-
- return count;
-}
-
-static AtkObject*
-gail_container_ref_child (AtkObject *obj,
- gint i)
-{
- GList *children, *tmp_list;
- AtkObject *accessible;
- GtkWidget *widget;
-
- g_return_val_if_fail (GAIL_IS_CONTAINER (obj), NULL);
- g_return_val_if_fail ((i >= 0), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return NULL;
-
- children = gtk_container_get_children (GTK_CONTAINER (widget));
- tmp_list = g_list_nth (children, i);
- if (!tmp_list)
- {
- g_list_free (children);
- return NULL;
- }
- accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
-
- g_list_free (children);
- g_object_ref (accessible);
- return accessible;
-}
-
-static gint
-gail_container_add_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data)
-{
- GailContainer *gail_container = GAIL_CONTAINER (data);
- GailContainerClass *klass;
-
- klass = GAIL_CONTAINER_GET_CLASS (gail_container);
-
- if (klass->add_gtk)
- return klass->add_gtk (container, widget, data);
- else
- return 1;
-}
-
-static gint
-gail_container_remove_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data)
-{
- GailContainer *gail_container = GAIL_CONTAINER (data);
- GailContainerClass *klass;
-
- klass = GAIL_CONTAINER_GET_CLASS (gail_container);
-
- if (klass->remove_gtk)
- return klass->remove_gtk (container, widget, data);
- else
- return 1;
-}
-
-static gint
-gail_container_real_add_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data)
-{
- AtkObject* atk_parent = ATK_OBJECT (data);
- AtkObject* atk_child = gtk_widget_get_accessible (widget);
- GailContainer *gail_container = GAIL_CONTAINER (atk_parent);
- gint index;
-
- g_object_notify (G_OBJECT (atk_child), "accessible_parent");
-
- g_list_free (gail_container->children);
- gail_container->children = gtk_container_get_children (container);
- index = g_list_index (gail_container->children, widget);
- g_signal_emit_by_name (atk_parent, "children_changed::add",
- index, atk_child, NULL);
-
- return 1;
-}
-
-static gint
-gail_container_real_remove_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data)
-{
- AtkPropertyValues values = { NULL };
- AtkObject* atk_parent;
- AtkObject *atk_child;
- GailContainer *gail_container;
- gint index;
-
- atk_parent = ATK_OBJECT (data);
- atk_child = gtk_widget_get_accessible (widget);
-
- if (atk_child)
- {
- g_value_init (&values.old_value, G_TYPE_POINTER);
- g_value_set_pointer (&values.old_value, atk_parent);
-
- values.property_name = "accessible-parent";
-
- g_object_ref (atk_child);
- g_signal_emit_by_name (atk_child,
- "property_change::accessible-parent", &values, NULL);
- g_object_unref (atk_child);
- }
- gail_container = GAIL_CONTAINER (atk_parent);
- index = g_list_index (gail_container->children, widget);
- g_list_free (gail_container->children);
- gail_container->children = gtk_container_get_children (container);
- if (index >= 0 && index <= g_list_length (gail_container->children))
- g_signal_emit_by_name (atk_parent, "children_changed::remove",
- index, atk_child, NULL);
-
- return 1;
-}
-
-static void
-gail_container_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GailContainer *container = GAIL_CONTAINER (obj);
-
- ATK_OBJECT_CLASS (gail_container_parent_class)->initialize (obj, data);
-
- container->children = gtk_container_get_children (GTK_CONTAINER (data));
-
- g_signal_connect (data, "add",
- G_CALLBACK (gail_container_add_gtk),
- obj);
- g_signal_connect (data, "remove",
- G_CALLBACK (gail_container_remove_gtk),
- obj);
-
- if (GTK_IS_TOOLBAR (data))
- obj->role = ATK_ROLE_TOOL_BAR;
- else if (GTK_IS_VIEWPORT (data))
- obj->role = ATK_ROLE_VIEWPORT;
- else
- obj->role = ATK_ROLE_PANEL;
-}
-
-static void
-gail_container_finalize (GObject *object)
-{
- GailContainer *container = GAIL_CONTAINER (object);
-
- g_list_free (container->children);
- G_OBJECT_CLASS (gail_container_parent_class)->finalize (object);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_CONTAINER_H__
-#define __GAIL_CONTAINER_H__
-
-#include "gailwidget.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_CONTAINER (gail_container_get_type ())
-#define GAIL_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CONTAINER, GailContainer))
-#define GAIL_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CONTAINER, GailContainerClass))
-#define GAIL_IS_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CONTAINER))
-#define GAIL_IS_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CONTAINER))
-#define GAIL_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CONTAINER, GailContainerClass))
-
-typedef struct _GailContainer GailContainer;
-typedef struct _GailContainerClass GailContainerClass;
-
-struct _GailContainer
-{
- GailWidget parent;
-
- /*
- * Cached list of children
- */
- GList *children;
-};
-
-GType gail_container_get_type (void);
-
-struct _GailContainerClass
-{
- GailWidgetClass parent_class;
-
- gint (*add_gtk) (GtkContainer *container,
- GtkWidget *widget,
- gpointer data);
- gint (*remove_gtk) (GtkContainer *container,
- GtkWidget *widget,
- gpointer data);
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_CONTAINER_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailcontainercell.h"
-
-static void gail_container_cell_class_init (GailContainerCellClass *klass);
-static void gail_container_cell_init (GailContainerCell *cell);
-static void gail_container_cell_finalize (GObject *obj);
-
-
-static void _gail_container_cell_recompute_child_indices
- (GailContainerCell *container);
-
-static void gail_container_cell_refresh_child_index (GailCell *cell);
-
-static gint gail_container_cell_get_n_children (AtkObject *obj);
-
-static AtkObject* gail_container_cell_ref_child (AtkObject *obj,
- gint child);
-
-G_DEFINE_TYPE (GailContainerCell, gail_container_cell, GAIL_TYPE_CELL)
-
-static void
-gail_container_cell_class_init (GailContainerCellClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS(klass);
- GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
-
- g_object_class->finalize = gail_container_cell_finalize;
-
- class->get_n_children = gail_container_cell_get_n_children;
- class->ref_child = gail_container_cell_ref_child;
-}
-
-static void
-gail_container_cell_init (GailContainerCell *cell)
-{
-}
-
-GailContainerCell *
-gail_container_cell_new (void)
-{
- GObject *object;
- AtkObject *atk_object;
- GailContainerCell *container;
-
- object = g_object_new (GAIL_TYPE_CONTAINER_CELL, NULL);
-
- g_return_val_if_fail (object != NULL, NULL);
-
- atk_object = ATK_OBJECT (object);
- atk_object->role = ATK_ROLE_TABLE_CELL;
-
- container = GAIL_CONTAINER_CELL(object);
- container->children = NULL;
- container->NChildren = 0;
- return container;
-}
-
-static void
-gail_container_cell_finalize (GObject *obj)
-{
- GailContainerCell *container = GAIL_CONTAINER_CELL (obj);
- GList *list;
-
- list = container->children;
- while (list)
- {
- g_object_unref (list->data);
- list = list->next;
- }
- g_list_free (container->children);
-
- G_OBJECT_CLASS (gail_container_cell_parent_class)->finalize (obj);
-}
-
-
-void
-gail_container_cell_add_child (GailContainerCell *container,
- GailCell *child)
-{
- gint child_index;
-
- g_return_if_fail (GAIL_IS_CONTAINER_CELL(container));
- g_return_if_fail (GAIL_IS_CELL(child));
-
- child_index = container->NChildren++;
- container->children = g_list_append (container->children, (gpointer) child);
- child->index = child_index;
- atk_object_set_parent (ATK_OBJECT (child), ATK_OBJECT (container));
- child->refresh_index = gail_container_cell_refresh_child_index;
-}
-
-
-void
-gail_container_cell_remove_child (GailContainerCell *container,
- GailCell *child)
-{
- g_return_if_fail (GAIL_IS_CONTAINER_CELL(container));
- g_return_if_fail (GAIL_IS_CELL(child));
- g_return_if_fail (container->NChildren > 0);
-
- container->children = g_list_remove (container->children, (gpointer) child);
- _gail_container_cell_recompute_child_indices (container);
- container->NChildren--;
-}
-
-
-static void
-_gail_container_cell_recompute_child_indices (GailContainerCell *container)
-{
- gint cur_index = 0;
- GList *temp_list;
-
- g_return_if_fail (GAIL_IS_CONTAINER_CELL(container));
-
- for (temp_list = container->children; temp_list; temp_list = temp_list->next)
- {
- GAIL_CELL(temp_list->data)->index = cur_index;
- cur_index++;
- }
-}
-
-
-static void
-gail_container_cell_refresh_child_index (GailCell *cell)
-{
- GailContainerCell *container;
- g_return_if_fail (GAIL_IS_CELL(cell));
- container = GAIL_CONTAINER_CELL (atk_object_get_parent (ATK_OBJECT(cell)));
- g_return_if_fail (GAIL_IS_CONTAINER_CELL (container));
- _gail_container_cell_recompute_child_indices (container);
-}
-
-
-
-static gint
-gail_container_cell_get_n_children (AtkObject *obj)
-{
- GailContainerCell *cell;
- g_return_val_if_fail (GAIL_IS_CONTAINER_CELL(obj), 0);
- cell = GAIL_CONTAINER_CELL(obj);
- return cell->NChildren;
-}
-
-
-static AtkObject *
-gail_container_cell_ref_child (AtkObject *obj,
- gint child)
-{
- GailContainerCell *cell;
- GList *list_node;
-
- g_return_val_if_fail (GAIL_IS_CONTAINER_CELL(obj), NULL);
- cell = GAIL_CONTAINER_CELL(obj);
-
- list_node = g_list_nth (cell->children, child);
- if (!list_node)
- return NULL;
-
- return g_object_ref (ATK_OBJECT (list_node->data));
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_CONTAINER_CELL_H__
-#define __GAIL_CONTAINER_CELL_H__
-
-#include <atk/atk.h>
-#include "gailcell.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_CONTAINER_CELL (gail_container_cell_get_type ())
-#define GAIL_CONTAINER_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_CONTAINER_CELL, GailContainerCell))
-#define GAIL_CONTAINER_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_CONTAINER_CELL, GailContainerCellClass))
-#define GAIL_IS_CONTAINER_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_CONTAINER_CELL))
-#define GAIL_IS_CONTAINER_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_CONTAINER_CELL))
-#define GAIL_CONTAINER_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_CONTAINER_CELL, GailContainerCellClass))
-
-typedef struct _GailContainerCell GailContainerCell;
-typedef struct _GailContainerCellClass GailContainerCellClass;
-
-struct _GailContainerCell
-{
- GailCell parent;
- GList *children;
- gint NChildren;
-};
-
-GType gail_container_cell_get_type (void);
-
-struct _GailContainerCellClass
-{
- GailCellClass parent_class;
-};
-
-GailContainerCell *
-gail_container_cell_new (void);
-
-void
-gail_container_cell_add_child (GailContainerCell *container,
- GailCell *child);
-
-void
-gail_container_cell_remove_child (GailContainerCell *container,
- GailCell *child);
-
-G_END_DECLS
-
-#endif /* __GAIL_TREE_VIEW_TEXT_CELL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "gailentry.h"
-#include "gailcombobox.h"
-#include <libgail-util/gailmisc.h>
-
-static void gail_entry_class_init (GailEntryClass *klass);
-static void gail_entry_init (GailEntry *entry);
-static void gail_entry_real_initialize (AtkObject *obj,
- gpointer data);
-static void text_setup (GailEntry *entry,
- GtkEntry *gtk_entry);
-static void gail_entry_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-static void gail_entry_finalize (GObject *object);
-
-static gint gail_entry_get_index_in_parent (AtkObject *accessible);
-
-/* atkobject.h */
-
-static AtkStateSet* gail_entry_ref_state_set (AtkObject *accessible);
-static AtkAttributeSet* gail_entry_get_attributes (AtkObject *accessible);
-
-/* atktext.h */
-
-static void atk_text_interface_init (AtkTextIface *iface);
-
-static gchar* gail_entry_get_text (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gunichar gail_entry_get_character_at_offset
- (AtkText *text,
- gint offset);
-static gchar* gail_entry_get_text_before_offset(AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_entry_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_entry_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gint gail_entry_get_caret_offset (AtkText *text);
-static gboolean gail_entry_set_caret_offset (AtkText *text,
- gint offset);
-static gint gail_entry_get_n_selections (AtkText *text);
-static gchar* gail_entry_get_selection (AtkText *text,
- gint selection_num,
- gint *start_offset,
- gint *end_offset);
-static gboolean gail_entry_add_selection (AtkText *text,
- gint start_offset,
- gint end_offset);
-static gboolean gail_entry_remove_selection (AtkText *text,
- gint selection_num);
-static gboolean gail_entry_set_selection (AtkText *text,
- gint selection_num,
- gint start_offset,
- gint end_offset);
-static gint gail_entry_get_character_count (AtkText *text);
-static AtkAttributeSet * gail_entry_get_run_attributes
- (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet * gail_entry_get_default_attributes
- (AtkText *text);
-static void gail_entry_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static gint gail_entry_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-/* atkeditabletext.h */
-
-static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
-static void gail_entry_set_text_contents (AtkEditableText *text,
- const gchar *string);
-static void gail_entry_insert_text (AtkEditableText *text,
- const gchar *string,
- gint length,
- gint *position);
-static void gail_entry_copy_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos);
-static void gail_entry_cut_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos);
-static void gail_entry_delete_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos);
-static void gail_entry_paste_text (AtkEditableText *text,
- gint position);
-static void gail_entry_paste_received (GtkClipboard *clipboard,
- const gchar *text,
- gpointer data);
-
-
-/* Callbacks */
-
-static gboolean gail_entry_idle_notify_insert (gpointer data);
-static void gail_entry_notify_insert (GailEntry *entry);
-static void gail_entry_notify_delete (GailEntry *entry);
-static void _gail_entry_insert_text_cb (GtkEntry *entry,
- gchar *arg1,
- gint arg2,
- gpointer arg3);
-static void _gail_entry_delete_text_cb (GtkEntry *entry,
- gint arg1,
- gint arg2);
-static void _gail_entry_changed_cb (GtkEntry *entry);
-static gboolean check_for_selection_change (GailEntry *entry,
- GtkEntry *gtk_entry);
-
-static void atk_action_interface_init (AtkActionIface *iface);
-
-static gboolean gail_entry_do_action (AtkAction *action,
- gint i);
-static gboolean idle_do_action (gpointer data);
-static gint gail_entry_get_n_actions (AtkAction *action);
-static const gchar* gail_entry_action_get_description (AtkAction *action,
- gint i);
-static const gchar* gail_entry_get_keybinding (AtkAction *action,
- gint i);
-static const gchar* gail_entry_action_get_name (AtkAction *action,
- gint i);
-static gboolean gail_entry_action_set_description (AtkAction *action,
- gint i,
- const gchar *desc);
-
-typedef struct _GailEntryPaste GailEntryPaste;
-
-struct _GailEntryPaste
-{
- GtkEntry* entry;
- gint position;
-};
-
-G_DEFINE_TYPE_WITH_CODE (GailEntry, gail_entry, GAIL_TYPE_WIDGET,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
-
-static void
-gail_entry_class_init (GailEntryClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailWidgetClass *widget_class;
-
- widget_class = (GailWidgetClass*)klass;
-
- gobject_class->finalize = gail_entry_finalize;
-
- class->ref_state_set = gail_entry_ref_state_set;
- class->get_index_in_parent = gail_entry_get_index_in_parent;
- class->initialize = gail_entry_real_initialize;
- class->get_attributes = gail_entry_get_attributes;
-
- widget_class->notify_gtk = gail_entry_real_notify_gtk;
-}
-
-static void
-gail_entry_init (GailEntry *entry)
-{
- entry->textutil = NULL;
- entry->signal_name_insert = NULL;
- entry->signal_name_delete = NULL;
- entry->cursor_position = 0;
- entry->selection_bound = 0;
- entry->activate_description = NULL;
- entry->activate_keybinding = NULL;
-}
-
-static void
-gail_entry_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkEntry *entry;
- GailEntry *gail_entry;
- gint start_pos, end_pos;
-
- ATK_OBJECT_CLASS (gail_entry_parent_class)->initialize (obj, data);
-
- gail_entry = GAIL_ENTRY (obj);
- gail_entry->textutil = gail_text_util_new ();
-
- g_assert (GTK_IS_ENTRY (data));
-
- entry = GTK_ENTRY (data);
- text_setup (gail_entry, entry);
- gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
- &start_pos, &end_pos);
- gail_entry->cursor_position = end_pos;
- gail_entry->selection_bound = start_pos;
-
- /* Set up signal callbacks */
- g_signal_connect (data, "insert-text",
- G_CALLBACK (_gail_entry_insert_text_cb), NULL);
- g_signal_connect (data, "delete-text",
- G_CALLBACK (_gail_entry_delete_text_cb), NULL);
- g_signal_connect (data, "changed",
- G_CALLBACK (_gail_entry_changed_cb), NULL);
-
- if (gtk_entry_get_visibility (entry))
- obj->role = ATK_ROLE_TEXT;
- else
- obj->role = ATK_ROLE_PASSWORD_TEXT;
-}
-
-static void
-gail_entry_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkWidget *widget;
- AtkObject* atk_obj;
- GtkEntry* gtk_entry;
- GailEntry* entry;
-
- widget = GTK_WIDGET (obj);
- atk_obj = gtk_widget_get_accessible (widget);
- gtk_entry = GTK_ENTRY (widget);
- entry = GAIL_ENTRY (atk_obj);
-
- if (strcmp (pspec->name, "cursor-position") == 0)
- {
- if (entry->insert_idle_handler == 0)
- entry->insert_idle_handler = gdk_threads_add_idle (gail_entry_idle_notify_insert, entry);
-
- if (check_for_selection_change (entry, gtk_entry))
- g_signal_emit_by_name (atk_obj, "text_selection_changed");
- /*
- * The entry cursor position has moved so generate the signal.
- */
- g_signal_emit_by_name (atk_obj, "text_caret_moved",
- entry->cursor_position);
- }
- else if (strcmp (pspec->name, "selection-bound") == 0)
- {
- if (entry->insert_idle_handler == 0)
- entry->insert_idle_handler = gdk_threads_add_idle (gail_entry_idle_notify_insert, entry);
-
- if (check_for_selection_change (entry, gtk_entry))
- g_signal_emit_by_name (atk_obj, "text_selection_changed");
- }
- else if (strcmp (pspec->name, "editable") == 0)
- {
- gboolean value;
-
- g_object_get (obj, "editable", &value, NULL);
- atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE,
- value);
- }
- else if (strcmp (pspec->name, "visibility") == 0)
- {
- gboolean visibility;
- AtkRole new_role;
-
- text_setup (entry, gtk_entry);
- visibility = gtk_entry_get_visibility (gtk_entry);
- new_role = visibility ? ATK_ROLE_TEXT : ATK_ROLE_PASSWORD_TEXT;
- atk_object_set_role (atk_obj, new_role);
- }
- else if (strcmp (pspec->name, "invisible-char") == 0)
- {
- text_setup (entry, gtk_entry);
- }
- else if (strcmp (pspec->name, "editing-canceled") == 0)
- {
- if (entry->insert_idle_handler)
- {
- g_source_remove (entry->insert_idle_handler);
- entry->insert_idle_handler = 0;
- }
- }
- else
- GAIL_WIDGET_CLASS (gail_entry_parent_class)->notify_gtk (obj, pspec);
-}
-
-static void
-text_setup (GailEntry *entry,
- GtkEntry *gtk_entry)
-{
- if (gtk_entry_get_visibility (gtk_entry))
- {
- gail_text_util_text_setup (entry->textutil, gtk_entry_get_text (gtk_entry));
- }
- else
- {
- gunichar invisible_char;
- GString *tmp_string = g_string_new (NULL);
- gint ch_len;
- gchar buf[7];
- guint length;
- gint i;
-
- invisible_char = gtk_entry_get_invisible_char (gtk_entry);
- if (invisible_char == 0)
- invisible_char = ' ';
-
- ch_len = g_unichar_to_utf8 (invisible_char, buf);
- length = gtk_entry_get_text_length (gtk_entry);
- for (i = 0; i < length; i++)
- {
- g_string_append_len (tmp_string, buf, ch_len);
- }
-
- gail_text_util_text_setup (entry->textutil, tmp_string->str);
- g_string_free (tmp_string, TRUE);
-
- }
-}
-
-static void
-gail_entry_finalize (GObject *object)
-{
- GailEntry *entry = GAIL_ENTRY (object);
-
- g_object_unref (entry->textutil);
- g_free (entry->activate_description);
- g_free (entry->activate_keybinding);
- if (entry->action_idle_handler)
- {
- g_source_remove (entry->action_idle_handler);
- entry->action_idle_handler = 0;
- }
- if (entry->insert_idle_handler)
- {
- g_source_remove (entry->insert_idle_handler);
- entry->insert_idle_handler = 0;
- }
- G_OBJECT_CLASS (gail_entry_parent_class)->finalize (object);
-}
-
-static gint
-gail_entry_get_index_in_parent (AtkObject *accessible)
-{
- /*
- * If the parent widget is a combo box then the index is 1
- * otherwise do the normal thing.
- */
- if (accessible->accessible_parent)
- if (GAIL_IS_COMBO_BOX (accessible->accessible_parent))
- return 1;
-
- return ATK_OBJECT_CLASS (gail_entry_parent_class)->get_index_in_parent (accessible);
-}
-
-/* atkobject.h */
-
-static AtkStateSet*
-gail_entry_ref_state_set (AtkObject *accessible)
-{
- AtkStateSet *state_set;
- GtkEntry *entry;
- gboolean value;
- GtkWidget *widget;
-
- state_set = ATK_OBJECT_CLASS (gail_entry_parent_class)->ref_state_set (accessible);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- return state_set;
-
- entry = GTK_ENTRY (widget);
-
- g_object_get (G_OBJECT (entry), "editable", &value, NULL);
- if (value)
- atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
- atk_state_set_add_state (state_set, ATK_STATE_SINGLE_LINE);
-
- return state_set;
-}
-
-static AtkAttributeSet *
-gail_entry_get_attributes (AtkObject *accessible)
-{
- GtkWidget *widget;
- AtkAttributeSet *attributes;
- AtkAttribute *placeholder_text;
- const gchar *text;
-
- attributes = ATK_OBJECT_CLASS (gail_entry_parent_class)->get_attributes (accessible);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- if (widget == NULL)
- return attributes;
-
- text = gtk_entry_get_placeholder_text (GTK_ENTRY (widget));
- if (text == NULL)
- return attributes;
-
- placeholder_text = g_malloc (sizeof (AtkAttribute));
- placeholder_text->name = g_strdup ("placeholder-text");
- placeholder_text->value = g_strdup (text);
-
- attributes = g_slist_append (attributes, placeholder_text);
-
- return attributes;
-}
-
-/* atktext.h */
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_entry_get_text;
- iface->get_character_at_offset = gail_entry_get_character_at_offset;
- iface->get_text_before_offset = gail_entry_get_text_before_offset;
- iface->get_text_at_offset = gail_entry_get_text_at_offset;
- iface->get_text_after_offset = gail_entry_get_text_after_offset;
- iface->get_caret_offset = gail_entry_get_caret_offset;
- iface->set_caret_offset = gail_entry_set_caret_offset;
- iface->get_character_count = gail_entry_get_character_count;
- iface->get_n_selections = gail_entry_get_n_selections;
- iface->get_selection = gail_entry_get_selection;
- iface->add_selection = gail_entry_add_selection;
- iface->remove_selection = gail_entry_remove_selection;
- iface->set_selection = gail_entry_set_selection;
- iface->get_run_attributes = gail_entry_get_run_attributes;
- iface->get_default_attributes = gail_entry_get_default_attributes;
- iface->get_character_extents = gail_entry_get_character_extents;
- iface->get_offset_at_point = gail_entry_get_offset_at_point;
-}
-
-static gchar*
-gail_entry_get_text (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- return gail_text_util_get_substring (GAIL_ENTRY (text)->textutil, start_pos, end_pos);
-}
-
-static gchar*
-gail_entry_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkEntry *entry;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get Entry */
- entry = GTK_ENTRY (widget);
-
- return gail_text_util_get_text (GAIL_ENTRY (text)->textutil,
- gtk_entry_get_layout (entry), GAIL_BEFORE_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_entry_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkEntry *entry;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get Entry */
- entry = GTK_ENTRY (widget);
-
- return gail_text_util_get_text (GAIL_ENTRY (text)->textutil,
- gtk_entry_get_layout (entry), GAIL_AT_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_entry_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkEntry *entry;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get Entry */
- entry = GTK_ENTRY (widget);
-
- return gail_text_util_get_text (GAIL_ENTRY (text)->textutil,
- gtk_entry_get_layout (entry), GAIL_AFTER_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gint
-gail_entry_get_character_count (AtkText *text)
-{
- GtkEntry *entry;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- entry = GTK_ENTRY (widget);
- return g_utf8_strlen (gtk_entry_get_text (entry), -1);
-}
-
-static gint
-gail_entry_get_caret_offset (AtkText *text)
-{
- GtkEntry *entry;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- entry = GTK_ENTRY (widget);
-
- return gtk_editable_get_position (GTK_EDITABLE (entry));
-}
-
-static gboolean
-gail_entry_set_caret_offset (AtkText *text, gint offset)
-{
- GtkEntry *entry;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- entry = GTK_ENTRY (widget);
-
- gtk_editable_set_position (GTK_EDITABLE (entry), offset);
- return TRUE;
-}
-
-static AtkAttributeSet*
-gail_entry_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkEntry *entry;
- AtkAttributeSet *at_set = NULL;
- GtkTextDirection dir;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- entry = GTK_ENTRY (widget);
-
- dir = gtk_widget_get_direction (widget);
- if (dir == GTK_TEXT_DIR_RTL)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_DIRECTION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
- }
-
- at_set = gail_misc_layout_get_run_attributes (at_set,
- gtk_entry_get_layout (entry),
- (gchar*)gtk_entry_get_text (entry),
- offset,
- start_offset,
- end_offset);
- return at_set;
-}
-
-static AtkAttributeSet*
-gail_entry_get_default_attributes (AtkText *text)
-{
- GtkWidget *widget;
- GtkEntry *entry;
- AtkAttributeSet *at_set = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- entry = GTK_ENTRY (widget);
-
- at_set = gail_misc_get_default_attributes (at_set,
- gtk_entry_get_layout (entry),
- widget);
- return at_set;
-}
-
-static void
-gail_entry_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkEntry *entry;
- PangoRectangle char_rect;
- gint index, x_layout, y_layout;
- const gchar *entry_text;
- gint start_pos, end_pos;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- entry = GTK_ENTRY (widget);
-
- gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
- &start_pos, &end_pos);
- gtk_entry_get_layout_offsets (entry, &x_layout, &y_layout);
- entry_text = gtk_entry_get_text (entry);
-
- index = g_utf8_offset_to_pointer (entry_text, offset) - entry_text;
-
- /* FIXME: entry->preedit cannot be accessed directly
- cursor_index = g_utf8_offset_to_pointer (entry_text, end_pos) - entry_text;
- if (index > cursor_index)
- index += entry->preedit_length;
- */
- pango_layout_index_to_pos (gtk_entry_get_layout(entry), index, &char_rect);
-
- gail_misc_get_extents_from_pango_rectangle (widget, &char_rect,
- x_layout, y_layout, x, y, width, height, coords);
-}
-
-static gint
-gail_entry_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkEntry *entry;
- gint index, x_layout, y_layout;
- const gchar *entry_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- entry = GTK_ENTRY (widget);
-
- gtk_entry_get_layout_offsets (entry, &x_layout, &y_layout);
- entry_text = gtk_entry_get_text (entry);
-
- index = gail_misc_get_index_at_point_in_layout (widget,
- gtk_entry_get_layout(entry), x_layout, y_layout, x, y, coords);
- if (index == -1)
- {
- if (coords == ATK_XY_SCREEN || coords == ATK_XY_WINDOW)
- return g_utf8_strlen (entry_text, -1);
-
- return index;
- }
- else
- {
- gint start_pos, end_pos;
-
- gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
- &start_pos, &end_pos);
- /* FIXME: entry->preedit_length cannot be accessed directly
- cursor_index = g_utf8_offset_to_pointer (entry_text, end_pos) - entry_text;
- if (index >= cursor_index && entry->preedit_length)
- {
- if (index >= cursor_index + entry->preedit_length)
- index -= entry->preedit_length;
- else
- index = cursor_index;
- }
- */
- return g_utf8_pointer_to_offset (entry_text, entry_text + index);
- }
-}
-
-static gint
-gail_entry_get_n_selections (AtkText *text)
-{
- GtkEntry *entry;
- GtkWidget *widget;
- gint select_start, select_end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- entry = GTK_ENTRY (widget);
-
- gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &select_start,
- &select_end);
-
- if (select_start != select_end)
- return 1;
- else
- return 0;
-}
-
-static gchar*
-gail_entry_get_selection (AtkText *text,
- gint selection_num,
- gint *start_pos,
- gint *end_pos)
-{
- GtkEntry *entry;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Only let the user get the selection if one is set, and if the
- * selection_num is 0.
- */
- if (selection_num != 0)
- return NULL;
-
- entry = GTK_ENTRY (widget);
- gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), start_pos, end_pos);
-
- if (*start_pos != *end_pos)
- return gtk_editable_get_chars (GTK_EDITABLE (entry), *start_pos, *end_pos);
- else
- return NULL;
-}
-
-static gboolean
-gail_entry_add_selection (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry;
- GtkWidget *widget;
- gint select_start, select_end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- entry = GTK_ENTRY (widget);
-
- gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &select_start,
- &select_end);
-
- /* If there is already a selection, then don't allow another to be added,
- * since GtkEntry only supports one selected region.
- */
- if (select_start == select_end)
- {
- gtk_editable_select_region (GTK_EDITABLE (entry), start_pos, end_pos);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gboolean
-gail_entry_remove_selection (AtkText *text,
- gint selection_num)
-{
- GtkEntry *entry;
- GtkWidget *widget;
- gint select_start, select_end, caret_pos;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- if (selection_num != 0)
- return FALSE;
-
- entry = GTK_ENTRY (widget);
- gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &select_start,
- &select_end);
-
- if (select_start != select_end)
- {
- /* Setting the start & end of the selected region to the caret position
- * turns off the selection.
- */
- caret_pos = gtk_editable_get_position (GTK_EDITABLE (entry));
- gtk_editable_select_region (GTK_EDITABLE (entry), caret_pos, caret_pos);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gboolean
-gail_entry_set_selection (AtkText *text,
- gint selection_num,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry;
- GtkWidget *widget;
- gint select_start, select_end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- /* Only let the user move the selection if one is set, and if the
- * selection_num is 0
- */
- if (selection_num != 0)
- return FALSE;
-
- entry = GTK_ENTRY (widget);
-
- gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &select_start,
- &select_end);
-
- if (select_start != select_end)
- {
- gtk_editable_select_region (GTK_EDITABLE (entry), start_pos, end_pos);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static void
-atk_editable_text_interface_init (AtkEditableTextIface *iface)
-{
- iface->set_text_contents = gail_entry_set_text_contents;
- iface->insert_text = gail_entry_insert_text;
- iface->copy_text = gail_entry_copy_text;
- iface->cut_text = gail_entry_cut_text;
- iface->delete_text = gail_entry_delete_text;
- iface->paste_text = gail_entry_paste_text;
- iface->set_run_attributes = NULL;
-}
-
-static void
-gail_entry_set_text_contents (AtkEditableText *text,
- const gchar *string)
-{
- GtkEntry *entry;
- GtkWidget *widget;
- GtkEditable *editable;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- entry = GTK_ENTRY (widget);
- editable = GTK_EDITABLE (entry);
- if (!gtk_editable_get_editable (editable))
- return;
-
- gtk_entry_set_text (entry, string);
-}
-
-static void
-gail_entry_insert_text (AtkEditableText *text,
- const gchar *string,
- gint length,
- gint *position)
-{
- GtkEntry *entry;
- GtkWidget *widget;
- GtkEditable *editable;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- entry = GTK_ENTRY (widget);
- editable = GTK_EDITABLE (entry);
- if (!gtk_editable_get_editable (editable))
- return;
-
- gtk_editable_insert_text (editable, string, length, position);
- gtk_editable_set_position (editable, *position);
-}
-
-static void
-gail_entry_copy_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry;
- GtkWidget *widget;
- GtkEditable *editable;
- gchar *str;
- GtkClipboard *clipboard;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- entry = GTK_ENTRY (widget);
- editable = GTK_EDITABLE (entry);
- str = gtk_editable_get_chars (editable, start_pos, end_pos);
- clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
- GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text (clipboard, str, -1);
-}
-
-static void
-gail_entry_cut_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry;
- GtkWidget *widget;
- GtkEditable *editable;
- gchar *str;
- GtkClipboard *clipboard;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- entry = GTK_ENTRY (widget);
- editable = GTK_EDITABLE (entry);
- if (!gtk_editable_get_editable (editable))
- return;
- str = gtk_editable_get_chars (editable, start_pos, end_pos);
- clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
- GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text (clipboard, str, -1);
- gtk_editable_delete_text (editable, start_pos, end_pos);
-}
-
-static void
-gail_entry_delete_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry;
- GtkWidget *widget;
- GtkEditable *editable;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- entry = GTK_ENTRY (widget);
- editable = GTK_EDITABLE (entry);
- if (!gtk_editable_get_editable (editable))
- return;
-
- gtk_editable_delete_text (editable, start_pos, end_pos);
-}
-
-static void
-gail_entry_paste_text (AtkEditableText *text,
- gint position)
-{
- GtkWidget *widget;
- GtkEditable *editable;
- GailEntryPaste paste_struct;
- GtkClipboard *clipboard;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- editable = GTK_EDITABLE (widget);
- if (!gtk_editable_get_editable (editable))
- return;
- paste_struct.entry = GTK_ENTRY (widget);
- paste_struct.position = position;
-
- g_object_ref (paste_struct.entry);
- clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
- GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_request_text (clipboard,
- gail_entry_paste_received, &paste_struct);
-}
-
-static void
-gail_entry_paste_received (GtkClipboard *clipboard,
- const gchar *text,
- gpointer data)
-{
- GailEntryPaste* paste_struct = (GailEntryPaste *)data;
-
- if (text)
- gtk_editable_insert_text (GTK_EDITABLE (paste_struct->entry), text, -1,
- &(paste_struct->position));
-
- g_object_unref (paste_struct->entry);
-}
-
-/* Callbacks */
-
-static gboolean
-gail_entry_idle_notify_insert (gpointer data)
-{
- GailEntry *entry;
-
- entry = GAIL_ENTRY (data);
- entry->insert_idle_handler = 0;
- gail_entry_notify_insert (entry);
-
- return FALSE;
-}
-
-static void
-gail_entry_notify_insert (GailEntry *entry)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (entry));
- if (gtk_entry_get_text_length (GTK_ENTRY (widget)) == 0)
- return;
-
- if (entry->signal_name_insert)
- {
- g_signal_emit_by_name (entry,
- entry->signal_name_insert,
- entry->position_insert,
- entry->length_insert);
- entry->signal_name_insert = NULL;
- }
-}
-
-/* Note arg1 returns the character at the start of the insert.
- * arg2 returns the number of characters inserted.
- */
-static void
-_gail_entry_insert_text_cb (GtkEntry *entry,
- gchar *arg1,
- gint arg2,
- gpointer arg3)
-{
- AtkObject *accessible;
- GailEntry *gail_entry;
- gint *position = (gint *) arg3;
-
- if (arg2 == 0)
- return;
-
- accessible = gtk_widget_get_accessible (GTK_WIDGET (entry));
- gail_entry = GAIL_ENTRY (accessible);
- if (!gail_entry->signal_name_insert)
- {
- gail_entry->signal_name_insert = "text_changed::insert";
- gail_entry->position_insert = *position;
- gail_entry->length_insert = g_utf8_strlen(arg1, arg2);
- }
- /*
- * The signal will be emitted when the cursor position is updated.
- * or in an idle handler if it not updated.
- */
- if (gail_entry->insert_idle_handler == 0)
- gail_entry->insert_idle_handler = gdk_threads_add_idle (gail_entry_idle_notify_insert, gail_entry);
-}
-
-static gunichar
-gail_entry_get_character_at_offset (AtkText *text,
- gint offset)
-{
- GtkWidget *widget;
- GailEntry *entry;
- gchar *string;
- gchar *index;
- gunichar unichar;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return '\0';
-
- entry = GAIL_ENTRY (text);
- string = gail_text_util_get_substring (entry->textutil, 0, -1);
- if (offset >= g_utf8_strlen (string, -1))
- {
- unichar = '\0';
- }
- else
- {
- index = g_utf8_offset_to_pointer (string, offset);
-
- unichar = g_utf8_get_char(index);
- }
-
- g_free(string);
- return unichar;
-}
-
-static void
-gail_entry_notify_delete (GailEntry *entry)
-{
- if (entry->signal_name_delete)
- {
- g_signal_emit_by_name (entry,
- entry->signal_name_delete,
- entry->position_delete,
- entry->length_delete);
- entry->signal_name_delete = NULL;
- }
-}
-
-/* Note arg1 returns the start of the delete range, arg2 returns the
- * end of the delete range if multiple characters are deleted.
- */
-static void
-_gail_entry_delete_text_cb (GtkEntry *entry,
- gint arg1,
- gint arg2)
-{
- AtkObject *accessible;
- GailEntry *gail_entry;
-
- /*
- * Zero length text deleted so ignore
- */
- if (arg2 - arg1 == 0)
- return;
-
- accessible = gtk_widget_get_accessible (GTK_WIDGET (entry));
- gail_entry = GAIL_ENTRY (accessible);
- if (!gail_entry->signal_name_delete)
- {
- gail_entry->signal_name_delete = "text_changed::delete";
- gail_entry->position_delete = arg1;
- gail_entry->length_delete = arg2 - arg1;
- }
- gail_entry_notify_delete (gail_entry);
-}
-
-static void
-_gail_entry_changed_cb (GtkEntry *entry)
-{
- AtkObject *accessible;
- GailEntry *gail_entry;
-
- accessible = gtk_widget_get_accessible (GTK_WIDGET (entry));
-
- gail_entry = GAIL_ENTRY (accessible);
-
- text_setup (gail_entry, entry);
-}
-
-static gboolean
-check_for_selection_change (GailEntry *entry,
- GtkEntry *gtk_entry)
-{
- gboolean selected, ret_val = FALSE;
- gint start_pos, end_pos;
-
- selected = gtk_editable_get_selection_bounds (GTK_EDITABLE (gtk_entry),
- &start_pos, &end_pos);
- if (selected)
- {
- if (end_pos != entry->cursor_position ||
- start_pos != entry->selection_bound)
- /*
- * This check is here as this function can be called
- * for notification of selection_bound and current_pos.
- * The values of current_pos and selection_bound may be the same
- * for both notifications and we only want to generate one
- * text_selection_changed signal.
- */
- ret_val = TRUE;
- }
- else
- {
- /* We had a selection */
- ret_val = (entry->cursor_position != entry->selection_bound);
- }
- entry->cursor_position = end_pos;
- entry->selection_bound = start_pos;
-
- return ret_val;
-}
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- iface->do_action = gail_entry_do_action;
- iface->get_n_actions = gail_entry_get_n_actions;
- iface->get_description = gail_entry_action_get_description;
- iface->get_keybinding = gail_entry_get_keybinding;
- iface->get_name = gail_entry_action_get_name;
- iface->set_description = gail_entry_action_set_description;
-}
-
-static gboolean
-gail_entry_do_action (AtkAction *action,
- gint i)
-{
- GailEntry *entry;
- GtkWidget *widget;
- gboolean return_value = TRUE;
-
- entry = GAIL_ENTRY (action);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- if (!gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- switch (i)
- {
- case 0:
- if (entry->action_idle_handler)
- return_value = FALSE;
- else
- entry->action_idle_handler = gdk_threads_add_idle (idle_do_action, entry);
- break;
- default:
- return_value = FALSE;
- break;
- }
- return return_value;
-}
-
-static gboolean
-idle_do_action (gpointer data)
-{
- GailEntry *entry;
- GtkWidget *widget;
-
- entry = GAIL_ENTRY (data);
- entry->action_idle_handler = 0;
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (entry));
- if (widget == NULL /* State is defunct */ ||
- !gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- gtk_widget_activate (widget);
-
- return FALSE;
-}
-
-static gint
-gail_entry_get_n_actions (AtkAction *action)
-{
- return 1;
-}
-
-static const gchar*
-gail_entry_action_get_description (AtkAction *action,
- gint i)
-{
- GailEntry *entry;
- const gchar *return_value;
-
- entry = GAIL_ENTRY (action);
- switch (i)
- {
- case 0:
- return_value = entry->activate_description;
- break;
- default:
- return_value = NULL;
- break;
- }
- return return_value;
-}
-
-static const gchar*
-gail_entry_get_keybinding (AtkAction *action,
- gint i)
-{
- GailEntry *entry;
- gchar *return_value = NULL;
-
- entry = GAIL_ENTRY (action);
- switch (i)
- {
- case 0:
- {
- /*
- * We look for a mnemonic on the label
- */
- GtkWidget *widget;
- GtkWidget *label;
- AtkRelationSet *set;
- AtkRelation *relation;
- GPtrArray *target;
- gpointer target_object;
- guint key_val;
-
- entry = GAIL_ENTRY (action);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (entry));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- /* Find labelled-by relation */
-
- set = atk_object_ref_relation_set (ATK_OBJECT (action));
- if (!set)
- return NULL;
- label = NULL;
- relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
- if (relation)
- {
- target = atk_relation_get_target (relation);
-
- target_object = g_ptr_array_index (target, 0);
- label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
- }
-
- g_object_unref (set);
-
- if (GTK_IS_LABEL (label))
- {
- key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
- if (key_val != GDK_KEY_VoidSymbol)
- return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
- }
- g_free (entry->activate_keybinding);
- entry->activate_keybinding = return_value;
- break;
- }
- default:
- break;
- }
- return return_value;
-}
-
-static const gchar*
-gail_entry_action_get_name (AtkAction *action,
- gint i)
-{
- const gchar *return_value;
-
- switch (i)
- {
- case 0:
- return_value = "activate";
- break;
- default:
- return_value = NULL;
- break;
- }
- return return_value;
-}
-
-static gboolean
-gail_entry_action_set_description (AtkAction *action,
- gint i,
- const gchar *desc)
-{
- GailEntry *entry;
- gchar **value;
-
- entry = GAIL_ENTRY (action);
- switch (i)
- {
- case 0:
- value = &entry->activate_description;
- break;
- default:
- value = NULL;
- break;
- }
-
- if (value)
- {
- g_free (*value);
- *value = g_strdup (desc);
- return TRUE;
- }
- else
- return FALSE;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_ENTRY_H__
-#define __GAIL_ENTRY_H__
-
-#include "gailwidget.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_ENTRY (gail_entry_get_type ())
-#define GAIL_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_ENTRY, GailEntry))
-#define GAIL_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_ENTRY, GailEntryClass))
-#define GAIL_IS_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_ENTRY))
-#define GAIL_IS_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_ENTRY))
-#define GAIL_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_ENTRY, GailEntryClass))
-
-typedef struct _GailEntry GailEntry;
-typedef struct _GailEntryClass GailEntryClass;
-
-struct _GailEntry
-{
- GailWidget parent;
-
- GailTextUtil *textutil;
- /*
- * These fields store information about text changed
- */
- gchar *signal_name_insert;
- gchar *signal_name_delete;
- gint position_insert;
- gint position_delete;
- gint length_insert;
- gint length_delete;
- gint cursor_position;
- gint selection_bound;
-
- gchar *activate_description;
- gchar *activate_keybinding;
- guint action_idle_handler;
- guint insert_idle_handler;
-};
-
-GType gail_entry_get_type (void);
-
-struct _GailEntryClass
-{
- GailWidgetClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_ENTRY_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "gailexpander.h"
-#include <libgail-util/gailmisc.h>
-
-static void gail_expander_class_init (GailExpanderClass *klass);
-static void gail_expander_init (GailExpander *expander);
-
-static const gchar* gail_expander_get_name (AtkObject *obj);
-static gint gail_expander_get_n_children (AtkObject *obj)
-;
-static AtkObject* gail_expander_ref_child (AtkObject *obj,
- gint i);
-
-static AtkStateSet* gail_expander_ref_state_set (AtkObject *obj);
-static void gail_expander_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-static void gail_expander_map_gtk (GtkWidget *widget,
- gpointer data);
-
-static void gail_expander_real_initialize (AtkObject *obj,
- gpointer data);
-static void gail_expander_finalize (GObject *object);
-static void gail_expander_init_textutil (GailExpander *expander,
- GtkExpander *widget);
-static const gchar* gail_expander_get_full_text (GtkExpander *widget);
-
-static void atk_action_interface_init (AtkActionIface *iface);
-static gboolean gail_expander_do_action (AtkAction *action,
- gint i);
-static gboolean idle_do_action (gpointer data);
-static gint gail_expander_get_n_actions(AtkAction *action);
-static const gchar* gail_expander_get_description
- (AtkAction *action,
- gint i);
-static const gchar* gail_expander_get_keybinding
- (AtkAction *action,
- gint i);
-static const gchar* gail_expander_action_get_name
- (AtkAction *action,
- gint i);
-static gboolean gail_expander_set_description
- (AtkAction *action,
- gint i,
- const gchar *desc);
-
-/* atktext.h */
-static void atk_text_interface_init (AtkTextIface *iface);
-
-static gchar* gail_expander_get_text (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gunichar gail_expander_get_character_at_offset
- (AtkText *text,
- gint offset);
-static gchar* gail_expander_get_text_before_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_expander_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_expander_get_text_after_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gint gail_expander_get_character_count(AtkText *text);
-static void gail_expander_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static gint gail_expander_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static AtkAttributeSet* gail_expander_get_run_attributes
- (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet* gail_expander_get_default_attributes
- (AtkText *text);
-
-G_DEFINE_TYPE_WITH_CODE (GailExpander, gail_expander, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
-
-static void
-gail_expander_class_init (GailExpanderClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailWidgetClass *widget_class;
-
- widget_class = (GailWidgetClass*)klass;
- widget_class->notify_gtk = gail_expander_real_notify_gtk;
-
- gobject_class->finalize = gail_expander_finalize;
-
- class->get_name = gail_expander_get_name;
- class->get_n_children = gail_expander_get_n_children;
- class->ref_child = gail_expander_ref_child;
- class->ref_state_set = gail_expander_ref_state_set;
-
- class->initialize = gail_expander_real_initialize;
-}
-
-static void
-gail_expander_init (GailExpander *expander)
-{
- expander->activate_description = NULL;
- expander->activate_keybinding = NULL;
- expander->action_idle_handler = 0;
- expander->textutil = NULL;
-}
-
-static const gchar*
-gail_expander_get_name (AtkObject *obj)
-{
- const gchar *name;
- g_return_val_if_fail (GAIL_IS_EXPANDER (obj), NULL);
-
- name = ATK_OBJECT_CLASS (gail_expander_parent_class)->get_name (obj);
- if (name != NULL)
- return name;
- else
- {
- /*
- * Get the text on the label
- */
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- g_return_val_if_fail (GTK_IS_EXPANDER (widget), NULL);
-
- return gail_expander_get_full_text (GTK_EXPANDER (widget));
- }
-}
-
-static gint
-gail_expander_get_n_children (AtkObject* obj)
-{
- GtkWidget *widget;
- GList *children;
- gint count = 0;
-
- g_return_val_if_fail (GAIL_IS_CONTAINER (obj), count);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return 0;
-
- children = gtk_container_get_children (GTK_CONTAINER(widget));
- count = g_list_length (children);
- g_list_free (children);
-
- /* See if there is a label - if there is, reduce our count by 1
- * since we don't want the label included with the children.
- */
- if (gtk_expander_get_label_widget (GTK_EXPANDER (widget)))
- count -= 1;
-
- return count;
-}
-
-static AtkObject*
-gail_expander_ref_child (AtkObject *obj,
- gint i)
-{
- GList *children, *tmp_list;
- AtkObject *accessible;
- GtkWidget *widget;
- GtkWidget *label;
- gint index;
-
- g_return_val_if_fail (GAIL_IS_CONTAINER (obj), NULL);
- g_return_val_if_fail ((i >= 0), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return NULL;
-
- children = gtk_container_get_children (GTK_CONTAINER (widget));
-
- /* See if there is a label - if there is, we need to skip it
- * since we don't want the label included with the children.
- */
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
- if (label) {
- for (index = 0; index <= i; index++) {
- tmp_list = g_list_nth (children, index);
- if (label == GTK_WIDGET (tmp_list->data)) {
- i += 1;
- break;
- }
- }
- }
-
- tmp_list = g_list_nth (children, i);
- if (!tmp_list)
- {
- g_list_free (children);
- return NULL;
- }
- accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
-
- g_list_free (children);
- g_object_ref (accessible);
- return accessible;
-}
-
-static void
-gail_expander_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GailExpander *gail_expander = GAIL_EXPANDER (obj);
- GtkWidget *expander;
-
- ATK_OBJECT_CLASS (gail_expander_parent_class)->initialize (obj, data);
-
- expander = GTK_WIDGET (data);
- if (gtk_widget_get_mapped (expander))
- gail_expander_init_textutil (gail_expander, GTK_EXPANDER (expander));
- else
- g_signal_connect (expander,
- "map",
- G_CALLBACK (gail_expander_map_gtk),
- gail_expander);
-
- obj->role = ATK_ROLE_TOGGLE_BUTTON;
-}
-
-static void
-gail_expander_map_gtk (GtkWidget *widget,
- gpointer data)
-{
- GailExpander *expander;
-
- expander = GAIL_EXPANDER (data);
- gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
-}
-
-static void
-gail_expander_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- AtkObject* atk_obj;
- GtkExpander *expander;
- GailExpander *gail_expander;
-
- expander = GTK_EXPANDER (obj);
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (expander));
-;
- if (strcmp (pspec->name, "label") == 0)
- {
- const gchar* label_text;
-
-
- label_text = gail_expander_get_full_text (expander);
-
- gail_expander = GAIL_EXPANDER (atk_obj);
- if (gail_expander->textutil)
- gail_text_util_text_setup (gail_expander->textutil, label_text);
-
- if (atk_obj->name == NULL)
- {
- /*
- * The label has changed so notify a change in accessible-name
- */
- g_object_notify (G_OBJECT (atk_obj), "accessible-name");
- }
- /*
- * The label is the only property which can be changed
- */
- g_signal_emit_by_name (atk_obj, "visible_data_changed");
- }
- else if (strcmp (pspec->name, "expanded") == 0)
- {
- atk_object_notify_state_change (atk_obj, ATK_STATE_CHECKED,
- gtk_expander_get_expanded (expander));
- atk_object_notify_state_change (atk_obj, ATK_STATE_EXPANDED,
- gtk_expander_get_expanded (expander));
- g_signal_emit_by_name (atk_obj, "visible_data_changed");
- }
- else
- GAIL_WIDGET_CLASS (gail_expander_parent_class)->notify_gtk (obj, pspec);
-}
-
-static const gchar*
-gail_expander_get_full_text (GtkExpander *widget)
-{
- GtkWidget *label_widget;
-
- label_widget = gtk_expander_get_label_widget (widget);
-
- if (!GTK_IS_LABEL (label_widget))
- return NULL;
-
- return gtk_label_get_text (GTK_LABEL (label_widget));
-}
-
-static void
-gail_expander_init_textutil (GailExpander *expander,
- GtkExpander *widget)
-{
- const gchar *label_text;
-
- expander->textutil = gail_text_util_new ();
- label_text = gail_expander_get_full_text (widget);
- gail_text_util_text_setup (expander->textutil, label_text);
-}
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- iface->do_action = gail_expander_do_action;
- iface->get_n_actions = gail_expander_get_n_actions;
- iface->get_description = gail_expander_get_description;
- iface->get_keybinding = gail_expander_get_keybinding;
- iface->get_name = gail_expander_action_get_name;
- iface->set_description = gail_expander_set_description;
-}
-
-static gboolean
-gail_expander_do_action (AtkAction *action,
- gint i)
-{
- GtkWidget *widget;
- GailExpander *expander;
- gboolean return_value = TRUE;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- expander = GAIL_EXPANDER (action);
- switch (i)
- {
- case 0:
- if (expander->action_idle_handler)
- return_value = FALSE;
- else
- expander->action_idle_handler = gdk_threads_add_idle (idle_do_action, expander);
- break;
- default:
- return_value = FALSE;
- break;
- }
- return return_value;
-}
-
-static gboolean
-idle_do_action (gpointer data)
-{
- GtkWidget *widget;
- GailExpander *gail_expander;
-
- gail_expander = GAIL_EXPANDER (data);
- gail_expander->action_idle_handler = 0;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gail_expander));
- if (widget == NULL /* State is defunct */ ||
- !gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- gtk_widget_activate (widget);
-
- return FALSE;
-}
-
-static gint
-gail_expander_get_n_actions (AtkAction *action)
-{
- return 1;
-}
-
-static const gchar*
-gail_expander_get_description (AtkAction *action,
- gint i)
-{
- GailExpander *expander;
- const gchar *return_value;
-
- expander = GAIL_EXPANDER (action);
-
- switch (i)
- {
- case 0:
- return_value = expander->activate_description;
- break;
- default:
- return_value = NULL;
- break;
- }
- return return_value;
-}
-
-static const gchar*
-gail_expander_get_keybinding (AtkAction *action,
- gint i)
-{
- GailExpander *expander;
- gchar *return_value = NULL;
-
- switch (i)
- {
- case 0:
- {
- /*
- * We look for a mnemonic on the label
- */
- GtkWidget *widget;
- GtkWidget *label;
-
- expander = GAIL_EXPANDER (action);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (expander));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- g_return_val_if_fail (GTK_IS_EXPANDER (widget), NULL);
-
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
- if (GTK_IS_LABEL (label))
- {
- guint key_val;
-
- key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
- if (key_val != GDK_KEY_VoidSymbol)
- return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
- g_free (expander->activate_keybinding);
- expander->activate_keybinding = return_value;
- }
- break;
- }
- default:
- break;
- }
- return return_value;
-}
-
-static const gchar*
-gail_expander_action_get_name (AtkAction *action,
- gint i)
-{
- const gchar *return_value;
-
- switch (i)
- {
- case 0:
- return_value = "activate";
- break;
- default:
- return_value = NULL;
- break;
- }
- return return_value;
-}
-
-static gboolean
-gail_expander_set_description (AtkAction *action,
- gint i,
- const gchar *desc)
-{
- GailExpander *expander;
- gchar **value;
-
- expander = GAIL_EXPANDER (action);
-
- switch (i)
- {
- case 0:
- value = &expander->activate_description;
- break;
- default:
- value = NULL;
- break;
- }
- if (value)
- {
- g_free (*value);
- *value = g_strdup (desc);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static AtkStateSet*
-gail_expander_ref_state_set (AtkObject *obj)
-{
- AtkStateSet *state_set;
- GtkWidget *widget;
- GtkExpander *expander;
-
- state_set = ATK_OBJECT_CLASS (gail_expander_parent_class)->ref_state_set (obj);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
-
- if (widget == NULL)
- return state_set;
-
- expander = GTK_EXPANDER (widget);
-
- atk_state_set_add_state (state_set, ATK_STATE_EXPANDABLE);
-
- if (gtk_expander_get_expanded (expander)) {
- atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
- atk_state_set_add_state (state_set, ATK_STATE_EXPANDED);
- }
-
- return state_set;
-}
-
-/* atktext.h */
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_expander_get_text;
- iface->get_character_at_offset = gail_expander_get_character_at_offset;
- iface->get_text_before_offset = gail_expander_get_text_before_offset;
- iface->get_text_at_offset = gail_expander_get_text_at_offset;
- iface->get_text_after_offset = gail_expander_get_text_after_offset;
- iface->get_character_count = gail_expander_get_character_count;
- iface->get_character_extents = gail_expander_get_character_extents;
- iface->get_offset_at_point = gail_expander_get_offset_at_point;
- iface->get_run_attributes = gail_expander_get_run_attributes;
- iface->get_default_attributes = gail_expander_get_default_attributes;
-}
-
-static gchar*
-gail_expander_get_text (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *widget;
- GailExpander *expander;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- expander = GAIL_EXPANDER (text);
- if (!expander->textutil)
- gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
-
- label_text = gail_expander_get_full_text (GTK_EXPANDER (widget));
-
- if (label_text == NULL)
- return NULL;
- else
- return gail_text_util_get_substring (expander->textutil,
- start_pos, end_pos);
-}
-
-static gchar*
-gail_expander_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GailExpander *expander;
- GtkWidget *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- expander = GAIL_EXPANDER (text);
- if (!expander->textutil)
- gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
-
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
- if (!GTK_IS_LABEL(label))
- return NULL;
- return gail_text_util_get_text (expander->textutil,
- gtk_label_get_layout (GTK_LABEL (label)),
- GAIL_BEFORE_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_expander_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GailExpander *expander;
- GtkWidget *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- expander = GAIL_EXPANDER (text);
- if (!expander->textutil)
- gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
-
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
- if (!GTK_IS_LABEL(label))
- return NULL;
- return gail_text_util_get_text (expander->textutil,
- gtk_label_get_layout (GTK_LABEL (label)),
- GAIL_AT_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_expander_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GailExpander *expander;
- GtkWidget *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- expander = GAIL_EXPANDER (text);
- if (!expander->textutil)
- gail_expander_init_textutil (expander, GTK_EXPANDER (widget));
-
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
- if (!GTK_IS_LABEL(label))
- return NULL;
- return gail_text_util_get_text (expander->textutil,
- gtk_label_get_layout (GTK_LABEL (label)),
- GAIL_AFTER_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gint
-gail_expander_get_character_count (AtkText *text)
-{
- GtkWidget *widget;
- GtkWidget *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
- if (!GTK_IS_LABEL(label))
- return 0;
-
- return g_utf8_strlen (gtk_label_get_text (GTK_LABEL (label)), -1);
-}
-
-static void
-gail_expander_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkWidget *label;
- PangoRectangle char_rect;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
- if (!GTK_IS_LABEL(label))
- return;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
- pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
-
- gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
- x_layout, y_layout, x, y, width, height, coords);
-}
-
-static gint
-gail_expander_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkWidget *label;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return -1;
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
-
- if (!GTK_IS_LABEL(label))
- return -1;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
-
- index = gail_misc_get_index_at_point_in_layout (label,
- gtk_label_get_layout (GTK_LABEL (label)),
- x_layout, y_layout, x, y, coords);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- if (index == -1)
- {
- if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
- return g_utf8_strlen (label_text, -1);
-
- return index;
- }
- else
- return g_utf8_pointer_to_offset (label_text, label_text + index);
-}
-
-static AtkAttributeSet*
-gail_expander_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- AtkAttributeSet *at_set = NULL;
- GtkJustification justify;
- GtkTextDirection dir;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- /* Get values set for entire label, if any */
- justify = gtk_label_get_justify (GTK_LABEL (label));
- if (justify != GTK_JUSTIFY_CENTER)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_JUSTIFICATION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
- }
- dir = gtk_widget_get_direction (label);
- if (dir == GTK_TEXT_DIR_RTL)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_DIRECTION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
- }
-
- at_set = gail_misc_layout_get_run_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- (gchar *) gtk_label_get_text (GTK_LABEL (label)),
- offset,
- start_offset,
- end_offset);
- return at_set;
-}
-
-static AtkAttributeSet*
-gail_expander_get_default_attributes (AtkText *text)
-{
- GtkWidget *widget;
- GtkWidget *label;
- AtkAttributeSet *at_set = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- at_set = gail_misc_get_default_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- widget);
- return at_set;
-}
-
-static gunichar
-gail_expander_get_character_at_offset (AtkText *text,
- gint offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- const gchar *string;
- gchar *index;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return '\0';
-
- label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
-
- if (!GTK_IS_LABEL(label))
- return '\0';
- string = gtk_label_get_text (GTK_LABEL (label));
- if (offset >= g_utf8_strlen (string, -1))
- return '\0';
- index = g_utf8_offset_to_pointer (string, offset);
-
- return g_utf8_get_char (index);
-}
-
-static void
-gail_expander_finalize (GObject *object)
-{
- GailExpander *expander = GAIL_EXPANDER (object);
-
- g_free (expander->activate_description);
- g_free (expander->activate_keybinding);
- if (expander->action_idle_handler)
- {
- g_source_remove (expander->action_idle_handler);
- expander->action_idle_handler = 0;
- }
- if (expander->textutil)
- g_object_unref (expander->textutil);
-
- G_OBJECT_CLASS (gail_expander_parent_class)->finalize (object);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_EXPANDER_H__
-#define __GAIL_EXPANDER_H__
-
-#include "gailcontainer.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_EXPANDER (gail_expander_get_type ())
-#define GAIL_EXPANDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_EXPANDER, GailExpander))
-#define GAIL_EXPANDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_EXPANDER, GailExpanderClass))
-#define GAIL_IS_EXPANDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_EXPANDER))
-#define GAIL_IS_EXPANDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_EXPANDER))
-#define GAIL_EXPANDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_EXPANDER, GailExpanderClass))
-
-typedef struct _GailExpander GailExpander;
-typedef struct _GailExpanderClass GailExpanderClass;
-
-struct _GailExpander
-{
- GailContainer parent;
-
- gchar *activate_description;
- gchar *activate_keybinding;
- guint action_idle_handler;
-
- GailTextUtil *textutil;
-};
-
-GType gail_expander_get_type (void);
-
-struct _GailExpanderClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_EXPANDER_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002 Sun Microsystems Inc.
- * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
- * Copyright (C) 2007 Christian Persch
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _GAIL_FACTORY_H__
-#define _GAIL_FACTORY_H__
-
-#include <glib-object.h>
-#include <atk/atk.h>
-
-#define _GAIL_IMPLEMENT_FACTORY_CREATE_ACCESSIBLE(GAIL_TYPE, TYPE) \
-{ \
- AtkObject *accessible; \
-\
- g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object, TYPE), NULL); \
-\
- accessible = g_object_new (GAIL_TYPE, NULL); \
- atk_object_initialize (accessible, object); \
-\
- return accessible; \
-}
-
-#define _GAIL_IMPLEMENT_FACTORY_BEGIN(GAIL_TYPE, TypeName, type_name) \
-\
-static GType \
-type_name##_factory_get_accessible_type (void) \
-{ \
- return GAIL_TYPE; \
-} \
-\
-static AtkObject* \
-type_name##_factory_create_accessible (GObject *object) \
-{
-
-#define _GAIL_IMPLEMENT_FACTORY_END(GAIL_TYPE, TypeName, type_name) \
-} \
-\
-static void \
-type_name##_factory_class_init (AtkObjectFactoryClass *klass) \
-{ \
- klass->create_accessible = type_name ## _factory_create_accessible; \
- klass->get_accessible_type = type_name ## _factory_get_accessible_type;\
-} \
-\
-GType \
-type_name##_factory_get_type (void) \
-{ \
- static volatile gsize g_define_type_id__volatile = 0; \
- if (g_once_init_enter (&g_define_type_id__volatile)) \
- { \
- GType g_define_type_id = \
- g_type_register_static_simple (ATK_TYPE_OBJECT_FACTORY, \
- g_intern_static_string (#TypeName "Factory"), \
- sizeof (AtkObjectFactoryClass), \
- (GClassInitFunc) type_name##_factory_class_init, \
- sizeof (AtkObjectFactory), \
- (GInstanceInitFunc) NULL, \
- (GTypeFlags) 0); \
- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
- } \
- return g_define_type_id__volatile; \
-}
-
-/* Implements a AtkObjectFactory creating accessibles of type
- * @GAIL_TYPE for objects of type @TYPE.
- */
-#define GAIL_IMPLEMENT_FACTORY(GAIL_TYPE, TypeName, type_name, TYPE) \
-_GAIL_IMPLEMENT_FACTORY_BEGIN (GAIL_TYPE, TypeName, type_name) \
-_GAIL_IMPLEMENT_FACTORY_CREATE_ACCESSIBLE (GAIL_TYPE, TYPE) \
-_GAIL_IMPLEMENT_FACTORY_END (GAIL_TYPE, TypeName, type_name)
-
-/* Implements a AtkObjectFactory creating accessibles of type
- * @GAIL_TYPE with creation func @create_accessible.
- */
-#define GAIL_IMPLEMENT_FACTORY_WITH_FUNC(GAIL_TYPE, TypeName, type_name, create_accessible) \
-_GAIL_IMPLEMENT_FACTORY_BEGIN (GAIL_TYPE, TypeName, type_name) \
-{ return create_accessible (GTK_WIDGET (object)); } \
-_GAIL_IMPLEMENT_FACTORY_END (GAIL_TYPE, TypeName, type_name)
-
-#define GAIL_IMPLEMENT_FACTORY_WITH_FUNC_DUMMY(GAIL_TYPE, TypeName, type_name, TYPE, create_accessible) \
-_GAIL_IMPLEMENT_FACTORY_BEGIN (GAIL_TYPE, TypeName, type_name) \
-{ \
- g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (object, TYPE), NULL);\
- return create_accessible (); \
-} \
-_GAIL_IMPLEMENT_FACTORY_END (GAIL_TYPE, TypeName, type_name)
-
-#define GAIL_WIDGET_SET_FACTORY(widget_type, type_as_function) \
- atk_registry_set_factory_type (atk_get_default_registry (), \
- widget_type, \
- type_as_function ## _factory_get_type ())
-
-#endif /* _GAIL_FACTORY_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailframe.h"
-
-static void gail_frame_class_init (GailFrameClass *klass);
-static void gail_frame_init (GailFrame *frame);
-static void gail_frame_initialize (AtkObject *accessible,
- gpointer data);
-static const gchar* gail_frame_get_name (AtkObject *obj);
-
-G_DEFINE_TYPE (GailFrame, gail_frame, GAIL_TYPE_CONTAINER)
-
-static void
-gail_frame_class_init (GailFrameClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->initialize = gail_frame_initialize;
- class->get_name = gail_frame_get_name;
-}
-
-static void
-gail_frame_init (GailFrame *frame)
-{
-}
-
-static void
-gail_frame_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_frame_parent_class)->initialize (accessible, data);
-
- accessible->role = ATK_ROLE_PANEL;
-}
-
-static const gchar*
-gail_frame_get_name (AtkObject *obj)
-{
- const gchar *name;
- g_return_val_if_fail (GAIL_IS_FRAME (obj), NULL);
-
- name = ATK_OBJECT_CLASS (gail_frame_parent_class)->get_name (obj);
- if (name != NULL)
- {
- return name;
- }
- else
- {
- /*
- * Get the text on the label
- */
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- {
- /*
- * State is defunct
- */
- return NULL;
- }
- return gtk_frame_get_label (GTK_FRAME (widget));
- }
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_FRAME_H__
-#define __GAIL_FRAME_H__
-
-#include "gailcontainer.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_FRAME (gail_frame_get_type ())
-#define GAIL_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_FRAME, GailFrame))
-#define GAIL_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_FRAME, GailFrameClass))
-#define GAIL_IS_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_FRAME))
-#define GAIL_IS_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_FRAME))
-#define GAIL_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_FRAME, GailFrameClass))
-
-typedef struct _GailFrame GailFrame;
-typedef struct _GailFrameClass GailFrameClass;
-
-struct _GailFrame
-{
- GailContainer parent;
-};
-
-GType gail_frame_get_type (void);
-
-struct _GailFrameClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_FRAME_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailhtmlbox.h"
-#include "gailhtmlview.h"
-#include <libgtkhtml/layout/htmlbox.h>
-
-static void gail_html_box_class_init (GailHtmlBoxClass *klass);
-static void gail_html_box_initialize (AtkObject *obj,
- gpointer data);
-static gint gail_html_box_get_index_in_parent (AtkObject *obj);
-static AtkStateSet* gail_html_box_ref_state_set (AtkObject *obj);
-
-static void gail_html_box_component_interface_init (AtkComponentIface *iface);
-static guint gail_html_box_add_focus_handler (AtkComponent *component,
- AtkFocusHandler handler);
-static void gail_html_box_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type);
-static gboolean gail_html_box_grab_focus (AtkComponent *component);
-static void gail_html_box_remove_focus_handler (AtkComponent *component,
- guint handler_id);
-
-G_DEFINE_TYPE_WITH_CODE (GailHtmlBox, gail_html_box, ATK_TYPE_GOBJECT,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, gail_html_box_component_interface_init))
-
-static void
-gail_html_box_class_init (GailHtmlBoxClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->get_index_in_parent = gail_html_box_get_index_in_parent;
- class->ref_state_set = gail_html_box_ref_state_set;
- class->initialize = gail_html_box_initialize;
-}
-
-static void
-gail_html_box_initialize (AtkObject *obj,
- gpointer data)
-{
- HtmlBox *box;
-
- ATK_OBJECT_CLASS (gail_html_box_parent_class)->initialize (obj, data);
-
- obj->role = ATK_ROLE_UNKNOWN;
-
- box = HTML_BOX (data);
-
- /*
- * We do not set the parent here for the root node of a HtmlView
- */
- if (box->parent)
- {
- atk_object_set_parent (obj,
- atk_gobject_get_accessible (G_OBJECT (box->parent)));
- }
-}
-
-static gint
-gail_html_box_get_index_in_parent (AtkObject *obj)
-{
- AtkObject *parent;
- AtkGObject *atk_gobj;
- HtmlBox *box;
- HtmlBox *parent_box;
- gint n_children = 0;
- GObject *g_obj;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX (obj), -1);
-
- atk_gobj = ATK_GOBJECT (obj);
- g_obj = atk_gobject_get_object (atk_gobj);
- if (g_obj == NULL)
- return -1;
-
- g_return_val_if_fail (HTML_IS_BOX (g_obj), -1);
- box = HTML_BOX (g_obj);
- parent = atk_object_get_parent (obj);
- if (GAIL_IS_HTML_VIEW (parent))
- {
- return 0;
- }
- else if (ATK_IS_GOBJECT (parent))
- {
- parent_box = HTML_BOX (atk_gobject_get_object (ATK_GOBJECT (parent)));
- }
- else
- {
- g_assert_not_reached ();
- return -1;
- }
-
- if (parent_box)
- {
- HtmlBox *child;
-
- child = parent_box->children;
-
- while (child)
- {
- if (child == box)
- return n_children;
-
- n_children++;
- child = child->next;
- }
- }
- return -1;
-}
-
-static AtkStateSet*
-gail_html_box_ref_state_set (AtkObject *obj)
-{
- AtkGObject *atk_gobj;
- GObject *g_obj;
- AtkStateSet *state_set;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX (obj), NULL);
- atk_gobj = ATK_GOBJECT (obj);
- state_set = ATK_OBJECT_CLASS (gail_html_box_parent_class)->ref_state_set (obj);
-
- g_obj = atk_gobject_get_object (atk_gobj);
- if (g_obj == NULL)
- {
- /* Object is defunct */
- atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
- }
- else
- {
- HtmlBox *box;
-
- box = HTML_BOX (g_obj);
-
- if (HTML_BOX_GET_STYLE (box)->display != HTML_DISPLAY_NONE)
- {
- atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
- atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
- }
- }
- return state_set;
-}
-
-static void
-gail_html_box_component_interface_init (AtkComponentIface *iface)
-{
- /*
- * Use default implementation for contains and get_position
- */
- iface->contains = NULL;
- iface->get_position = NULL;
- iface->add_focus_handler = gail_html_box_add_focus_handler;
- iface->get_extents = gail_html_box_get_extents;
- iface->get_size = NULL;
- iface->grab_focus = gail_html_box_grab_focus;
- iface->remove_focus_handler = gail_html_box_remove_focus_handler;
- iface->set_extents = NULL;
- iface->set_position = NULL;
- iface->set_size = NULL;
-}
-
-static guint
-gail_html_box_add_focus_handler (AtkComponent *component,
- AtkFocusHandler handler)
-{
- return g_signal_connect_closure (component,
- "focus-event",
- g_cclosure_new (
- G_CALLBACK (handler), NULL,
- (GClosureNotify) NULL),
- FALSE);
-}
-
-static void
-gail_html_box_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type)
-{
- AtkGObject *atk_gobj;
- HtmlBox *box;
- GObject *g_obj;
-
- g_return_if_fail (GAIL_IS_HTML_BOX (component));
-
- atk_gobj = ATK_GOBJECT (component);
- g_obj = atk_gobject_get_object (atk_gobj);
- if (g_obj == NULL)
- return;
-
- g_return_if_fail (HTML_IS_BOX (g_obj));
- box = HTML_BOX (g_obj);
-
- *x = html_box_get_absolute_x (box);
- *y = html_box_get_absolute_y (box);
- *width = box->width;
- *height = box->height;
-
- g_print ("%d %d %d %d\n",
- html_box_get_absolute_x (box),
- html_box_get_absolute_y (box),
- html_box_get_containing_block_width (box),
- html_box_get_containing_block_height (box));
-}
-
-static gboolean
-gail_html_box_grab_focus (AtkComponent *component)
-{
- return TRUE;
-}
-
-static void
-gail_html_box_remove_focus_handler (AtkComponent *component,
- guint handler_id)
-{
- g_signal_handler_disconnect (ATK_OBJECT (component), handler_id);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_HTML_BOX_H__
-#define __GAIL_HTML_BOX_H__
-
-#include <atk/atk.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_HTML_BOX (gail_html_box_get_type ())
-#define GAIL_HTML_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_HTML_BOX, GailHtmlBox))
-#define GAIL_HTML_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_HTML_BOX, GailHtmlBoxClass))
-#define GAIL_IS_HTML_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_HTML_BOX))
-#define GAIL_IS_HTML_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_HTML_BOX))
-#define GAIL_HTML_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_HTML_BOX, GailHtmlBoxClass))
-
-typedef struct _GailHtmlBox GailHtmlBox;
-typedef struct _GailHtmlBoxClass GailHtmlBoxClass;
-
-struct _GailHtmlBox
-{
- AtkGObject parent;
-};
-
-struct _GailHtmlBoxClass
-{
- AtkGObjectClass parent_class;
-};
-
-GType gail_html_box_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GAIL_HTML_BOX_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <libgtkhtml/gtkhtml.h>
-#include "gailhtmlboxblock.h"
-
-static void gail_html_box_block_class_init (GailHtmlBoxBlockClass *klass);
-static gint gail_html_box_block_get_n_children (AtkObject *obj);
-static AtkObject* gail_html_box_block_ref_child (AtkObject *obj,
- gint i);
-
-G_DEFINE_TYPE (GailHtmlBoxBlock, gail_html_box_block, GAIL_TYPE_HTML_BOX)
-
-AtkObject*
-gail_html_box_block_new (GObject *obj)
-{
- GObject *object;
- AtkObject *atk_object;
-
- g_return_val_if_fail (HTML_IS_BOX_BLOCK (obj), NULL);
- object = g_object_new (GAIL_TYPE_HTML_BOX_BLOCK, NULL);
- atk_object = ATK_OBJECT (object);
- atk_object_initialize (atk_object, obj);
- atk_object->role = ATK_ROLE_PANEL;
- return atk_object;
-}
-
-static void
-gail_html_box_block_class_init (GailHtmlBoxBlockClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->get_n_children = gail_html_box_block_get_n_children;
- class->ref_child = gail_html_box_block_ref_child;
-}
-
-static gint
-gail_html_box_block_get_n_children (AtkObject *obj)
-{
- AtkGObject *atk_gobject;
- HtmlBox *box;
- gint n_children = 0;
- GObject *g_obj;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX_BLOCK (obj), 0);
- atk_gobject = ATK_GOBJECT (obj);
- g_obj = atk_gobject_get_object (atk_gobject);
- if (g_obj == NULL)
- return 0;
-
- g_return_val_if_fail (HTML_IS_BOX (g_obj), 0);
- box = HTML_BOX (g_obj);
-
- if (box)
- {
- HtmlBox *child;
-
- child = box->children;
-
- while (child)
- {
- n_children++;
- child = child->next;
- }
- }
- return n_children;
-}
-
-static AtkObject *
-gail_html_box_block_ref_child (AtkObject *obj,
- gint i)
-{
- AtkGObject *atk_gobject;
- GObject *g_obj;
- HtmlBox *box;
- AtkObject *atk_child = NULL;
- gint n_children = 0;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX_BLOCK (obj), NULL);
- atk_gobject = ATK_GOBJECT (obj);
- g_obj = atk_gobject_get_object (atk_gobject);
- if (g_obj == NULL)
- return NULL;
-
- g_return_val_if_fail (HTML_IS_BOX (g_obj), NULL);
- box = HTML_BOX (g_obj);
-
- if (box)
- {
- HtmlBox *child;
-
- child = box->children;
-
- while (child)
- {
- if (n_children == i)
- {
- atk_child = atk_gobject_get_accessible (G_OBJECT (child));
- g_object_ref (atk_child);
- break;
- }
- n_children++;
- child = child->next;
- }
- }
- return atk_child;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <libgtkhtml/gtkhtml.h>
-#include "gailhtmlboxembedded.h"
-
-static void gail_html_box_embedded_class_init (GailHtmlBoxEmbeddedClass *klass);
-static gint gail_html_box_embedded_get_n_children (AtkObject *obj);
-static AtkObject* gail_html_box_embedded_ref_child (AtkObject *obj,
- gint i);
-
-G_DEFINE_TYPE (GailHtmlBoxEmbedded, gail_html_box_embedded, GAIL_TYPE_HTML_BOX)
-
-AtkObject*
-gail_html_box_embedded_new (GObject *obj)
-{
- gpointer object;
- AtkObject *atk_object;
-
- g_return_val_if_fail (HTML_IS_BOX_EMBEDDED (obj), NULL);
- object = g_object_new (GAIL_TYPE_HTML_BOX_EMBEDDED, NULL);
- atk_object = ATK_OBJECT (object);
- atk_object_initialize (atk_object, obj);
- atk_object->role = ATK_ROLE_PANEL;
- return atk_object;
-}
-
-static void
-gail_html_box_embedded_class_init (GailHtmlBoxEmbeddedClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->get_n_children = gail_html_box_embedded_get_n_children;
- class->ref_child = gail_html_box_embedded_ref_child;
-}
-
-static gint
-gail_html_box_embedded_get_n_children (AtkObject *obj)
-{
- AtkGObject *atk_gobject;
- HtmlBoxEmbedded *box_embedded;
- GObject *g_obj;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX_EMBEDDED (obj), 0);
- atk_gobject = ATK_GOBJECT (obj);
- g_obj = atk_gobject_get_object (atk_gobject);
- if (g_obj == NULL)
- /* State is defunct */
- return 0;
-
- g_return_val_if_fail (HTML_IS_BOX_EMBEDDED (g_obj), 0);
-
- box_embedded = HTML_BOX_EMBEDDED (g_obj);
- g_return_val_if_fail (box_embedded->widget, 0);
- return 1;
-}
-
-static AtkObject*
-gail_html_box_embedded_ref_child (AtkObject *obj,
- gint i)
-{
- AtkGObject *atk_gobject;
- HtmlBoxEmbedded *box_embedded;
- GObject *g_obj;
- AtkObject *atk_child;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX_EMBEDDED (obj), NULL);
-
- if (i != 0)
- return NULL;
-
- atk_gobject = ATK_GOBJECT (obj);
- g_obj = atk_gobject_get_object (atk_gobject);
- if (g_obj == NULL)
- /* State is defunct */
- return NULL;
-
- g_return_val_if_fail (HTML_IS_BOX_EMBEDDED (g_obj), NULL);
-
- box_embedded = HTML_BOX_EMBEDDED (g_obj);
- g_return_val_if_fail (box_embedded->widget, NULL);
-
- atk_child = gtk_widget_get_accessible (box_embedded->widget);
- g_object_ref (atk_child);
- atk_object_set_parent (atk_child, obj);
- return atk_child;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gailhtmlboxtext.h"
-
-static void gail_html_box_text_class_init (GailHtmlBoxTextClass *klass);
-static void gail_html_box_text_text_interface_init (AtkTextIface *iface);
-static gchar* gail_html_box_text_get_text (AtkText *text,
- gint start_offset,
- gint end_offset);
-static gchar* gail_html_box_text_get_text_after_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_html_box_text_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_html_box_text_get_text_before_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gunichar gail_html_box_text_get_character_at_offset
- (AtkText *text,
- gint offset);
-static gint gail_html_box_text_get_character_count (AtkText *text);
-static gint gail_html_box_text_get_caret_offset (AtkText *text);
-static gboolean gail_html_box_text_set_caret_offset (AtkText *text,
- gint offset);
-static gint gail_html_box_text_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static void gail_html_box_text_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static AtkAttributeSet*
- gail_html_box_text_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet*
- gail_html_box_text_get_default_attributes (AtkText *text);
-static gint gail_html_box_text_get_n_selections (AtkText *text);
-static gchar* gail_html_box_text_get_selection (AtkText *text,
- gint selection_num,
- gint *start_pos,
- gint *end_pos);
-static gboolean gail_html_box_text_add_selection (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gboolean gail_html_box_text_remove_selection (AtkText *text,
- gint selection_num);
-static gboolean gail_html_box_text_set_selection (AtkText *text,
- gint selection_num,
- gint start_pos,
- gint end_pos);
-static AtkAttributeSet*
- add_to_attr_set (AtkAttributeSet *attrib_set,
- GtkTextAttributes *attrs,
- AtkTextAttribute attr);
-static gchar* get_text_near_offset (AtkText *text,
- GailOffsetType function,
- AtkTextBoundary boundary_type,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-
-G_DEFINE_TYPE_WITH_CODE (GailHtmlBoxText, gail_html_box_text, GAIL_TYPE_HTML_BOX,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, gail_html_box_text_text_interface_init))
-
-AtkObject*
-gail_html_box_text_new (GObject *obj)
-{
- gpointer object;
- AtkObject *atk_object;
- GailHtmlBoxText *gail_text;
-
- g_return_val_if_fail (HTML_IS_BOX_TEXT (obj), NULL);
- object = g_object_new (GAIL_TYPE_HTML_BOX_TEXT, NULL);
- atk_object = ATK_OBJECT (object);
- gail_text = GAIL_HTML_BOX_TEXT (object);
-
- atk_object_initialize (atk_object, obj);
- gail_text->texthelper = gail_text_helper_new ();
-#if 0
- gail_text_helper_text_setup (gail_text->texthelper,
- HTML_BOX_TEXT (obj)->master->text);
-#endif
-
- atk_object->role = ATK_ROLE_TEXT;
- return atk_object;
-}
-
-static void
-gail_html_box_text_class_init (GailHtmlBoxTextClass *klass)
-{
-}
-
-static void
-gail_html_box_text_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_html_box_text_get_text;
- iface->get_text_after_offset = gail_html_box_text_get_text_after_offset;
- iface->get_text_at_offset = gail_html_box_text_get_text_at_offset;
- iface->get_text_before_offset = gail_html_box_text_get_text_before_offset;
- iface->get_character_at_offset = gail_html_box_text_get_character_at_offset;
- iface->get_character_count = gail_html_box_text_get_character_count;
- iface->get_caret_offset = gail_html_box_text_get_caret_offset;
- iface->set_caret_offset = gail_html_box_text_set_caret_offset;
- iface->get_offset_at_point = gail_html_box_text_get_offset_at_point;
- iface->get_character_extents = gail_html_box_text_get_character_extents;
- iface->get_n_selections = gail_html_box_text_get_n_selections;
- iface->get_selection = gail_html_box_text_get_selection;
- iface->add_selection = gail_html_box_text_add_selection;
- iface->remove_selection = gail_html_box_text_remove_selection;
- iface->set_selection = gail_html_box_text_set_selection;
- iface->get_run_attributes = gail_html_box_text_get_run_attributes;
- iface->get_default_attributes = gail_html_box_text_get_default_attributes;
-}
-
-static gchar*
-gail_html_box_text_get_text (AtkText *text,
- gint start_offset,
- gint end_offset)
-{
- GailHtmlBoxText *gail_text;
- GtkTextBuffer *buffer;
- GtkTextIter start, end;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), NULL);
- gail_text = GAIL_HTML_BOX_TEXT (text);
- g_return_val_if_fail (gail_text->texthelper, NULL);
-
- buffer = gail_text->texthelper->buffer;
- gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
- gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
-
- return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
-}
-
-static gchar*
-gail_html_box_text_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- return get_text_near_offset (text, GAIL_AFTER_OFFSET,
- boundary_type, offset,
- start_offset, end_offset);
-}
-
-static gchar*
-gail_html_box_text_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- return get_text_near_offset (text, GAIL_AT_OFFSET,
- boundary_type, offset,
- start_offset, end_offset);
-}
-
-static gchar*
-gail_html_box_text_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- return get_text_near_offset (text, GAIL_BEFORE_OFFSET,
- boundary_type, offset,
- start_offset, end_offset);
-}
-
-static gunichar
-gail_html_box_text_get_character_at_offset (AtkText *text,
- gint offset)
-{
- GailHtmlBoxText *gail_item;
- GtkTextIter start, end;
- GtkTextBuffer *buffer;
- gchar *string;
- gchar *index;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), 0);
- gail_item = GAIL_HTML_BOX_TEXT (text);
- buffer = gail_item->texthelper->buffer;
- gtk_text_buffer_get_start_iter (buffer, &start);
- gtk_text_buffer_get_end_iter (buffer, &end);
- string = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- index = g_utf8_offset_to_pointer (string, offset);
- g_free (string);
-
- return g_utf8_get_char (index);
-}
-
-static gint
-gail_html_box_text_get_character_count (AtkText *text)
-{
- GtkTextBuffer *buffer;
- GailHtmlBoxText *gail_text;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), 0);
- gail_text = GAIL_HTML_BOX_TEXT (text);
- g_return_val_if_fail (gail_text->texthelper, 0);
- buffer = gail_text->texthelper->buffer;
- return gtk_text_buffer_get_char_count (buffer);
-}
-
-static gint
-gail_html_box_text_get_caret_offset (AtkText *text)
-{
- GailHtmlBoxText *gail_text;
- GtkTextBuffer *buffer;
- GtkTextMark *cursor_mark;
- GtkTextIter cursor_itr;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), 0);
- gail_text = GAIL_HTML_BOX_TEXT (text);
- g_return_val_if_fail (gail_text->texthelper, 0);
- buffer = gail_text->texthelper->buffer;
- cursor_mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &cursor_itr, cursor_mark);
- return gtk_text_iter_get_offset (&cursor_itr);
-}
-
-static gboolean
-gail_html_box_text_set_caret_offset (AtkText *text,
- gint offset)
-{
- GailHtmlBoxText *gail_text;
- GtkTextBuffer *buffer;
- GtkTextIter pos_itr;
-
- g_return_val_if_fail (GAIL_IS_HTML_BOX_TEXT (text), FALSE);
- gail_text = GAIL_HTML_BOX_TEXT (text);
- g_return_val_if_fail (gail_text->texthelper, FALSE);
- buffer = gail_text->texthelper->buffer;
- gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, offset);
- gtk_text_buffer_move_mark_by_name (buffer, "insert", &pos_itr);
- return TRUE;
-}
-
-static gint
-gail_html_box_text_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- return -1;
-}
-
-static void
-gail_html_box_text_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- return;
-}
-
-static AtkAttributeSet*
-gail_html_box_text_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- return NULL;
-}
-
-static AtkAttributeSet*
-gail_html_box_text_get_default_attributes (AtkText *text)
-{
- return NULL;
-}
-
-static gint
-gail_html_box_text_get_n_selections (AtkText *text)
-{
- return 0;
-}
-
-static gchar*
-gail_html_box_text_get_selection (AtkText *text,
- gint selection_num,
- gint *start_pos,
- gint *end_pos)
-{
- return NULL;
-}
-
-static gboolean
-gail_html_box_text_add_selection (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- return FALSE;
-}
-
-static gboolean
-gail_html_box_text_remove_selection (AtkText *text,
- gint selection_num)
-{
- return FALSE;
-}
-
-static gboolean
-gail_html_box_text_set_selection (AtkText *text,
- gint selection_num,
- gint start_pos,
- gint end_pos)
-{
- return FALSE;
-}
-
-static AtkAttributeSet*
-add_to_attr_set (AtkAttributeSet *attrib_set,
- GtkTextAttributes *attrs,
- AtkTextAttribute attr)
-{
- gchar *value;
-
- switch (attr)
- {
- case ATK_TEXT_ATTR_LEFT_MARGIN:
- value = g_strdup_printf ("%i", attrs->left_margin);
- break;
- case ATK_TEXT_ATTR_RIGHT_MARGIN:
- value = g_strdup_printf ("%i", attrs->right_margin);
- break;
- case ATK_TEXT_ATTR_INDENT:
- value = g_strdup_printf ("%i", attrs->indent);
- break;
- case ATK_TEXT_ATTR_INVISIBLE:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->invisible));
- break;
- case ATK_TEXT_ATTR_EDITABLE:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->editable));
- break;
- case ATK_TEXT_ATTR_PIXELS_ABOVE_LINES:
- value = g_strdup_printf ("%i", attrs->pixels_above_lines);
- break;
- case ATK_TEXT_ATTR_PIXELS_BELOW_LINES:
- value = g_strdup_printf ("%i", attrs->pixels_below_lines);
- break;
- case ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP:
- value = g_strdup_printf ("%i", attrs->pixels_inside_wrap);
- break;
- case ATK_TEXT_ATTR_BG_FULL_HEIGHT:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->bg_full_height));
- break;
- case ATK_TEXT_ATTR_RISE:
- value = g_strdup_printf ("%i", attrs->appearance.rise);
- break;
- case ATK_TEXT_ATTR_UNDERLINE:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.underline));
- break;
- case ATK_TEXT_ATTR_STRIKETHROUGH:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.strikethrough));
- break;
- case ATK_TEXT_ATTR_SIZE:
- value = g_strdup_printf ("%i",
- pango_font_description_get_size (attrs->font));
- break;
- case ATK_TEXT_ATTR_SCALE:
- value = g_strdup_printf ("%g", attrs->font_scale);
- break;
- case ATK_TEXT_ATTR_WEIGHT:
- value = g_strdup_printf ("%d",
- pango_font_description_get_weight (attrs->font));
- break;
- case ATK_TEXT_ATTR_LANGUAGE:
- value = g_strdup ((gchar *)(attrs->language));
- break;
- case ATK_TEXT_ATTR_FAMILY_NAME:
- value = g_strdup (pango_font_description_get_family (attrs->font));
- break;
- case ATK_TEXT_ATTR_BG_COLOR:
- value = g_strdup_printf ("%u,%u,%u",
- attrs->appearance.bg_color.red,
- attrs->appearance.bg_color.green,
- attrs->appearance.bg_color.blue);
- break;
- case ATK_TEXT_ATTR_FG_COLOR:
- value = g_strdup_printf ("%u,%u,%u",
- attrs->appearance.fg_color.red,
- attrs->appearance.fg_color.green,
- attrs->appearance.fg_color.blue);
- break;
- case ATK_TEXT_ATTR_BG_STIPPLE:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.bg_stipple ? 1 : 0));
- break;
- case ATK_TEXT_ATTR_FG_STIPPLE:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.fg_stipple ? 1 : 0));
- break;
- case ATK_TEXT_ATTR_WRAP_MODE:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->wrap_mode));
- break;
- case ATK_TEXT_ATTR_DIRECTION:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->direction));
- break;
- case ATK_TEXT_ATTR_JUSTIFICATION:
- value = g_strdup (atk_text_attribute_get_value (attr, attrs->justification));
- break;
- case ATK_TEXT_ATTR_STRETCH:
- value = g_strdup (atk_text_attribute_get_value (attr,
- pango_font_description_get_stretch (attrs->font)));
- break;
- case ATK_TEXT_ATTR_VARIANT:
- value = g_strdup (atk_text_attribute_get_value (attr,
- pango_font_description_get_variant (attrs->font)));
- break;
- case ATK_TEXT_ATTR_STYLE:
- value = g_strdup (atk_text_attribute_get_value (attr,
- pango_font_description_get_style (attrs->font)));
- break;
- default:
- value = NULL;
- break;
- }
- return gail_text_helper_add_attribute (attrib_set,
- attr,
- value);
-}
-
-static gchar*
-get_text_near_offset (AtkText *text,
- GailOffsetType function,
- AtkTextBoundary boundary_type,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- return gail_text_helper_get_text (GAIL_HTML_BOX_TEXT (text)->texthelper, NULL,
- function, boundary_type, offset,
- start_offset, end_offset);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailimage.h"
-
-static void gail_image_class_init (GailImageClass *klass);
-static void gail_image_init (GailImage *image);
-static void gail_image_initialize (AtkObject *accessible,
- gpointer data);
-static const gchar* gail_image_get_name (AtkObject *accessible);
-
-
-static void atk_image_interface_init (AtkImageIface *iface);
-
-static const gchar *
- gail_image_get_image_description (AtkImage *image);
-static void gail_image_get_image_position (AtkImage *image,
- gint *x,
- gint *y,
- AtkCoordType coord_type);
-static void gail_image_get_image_size (AtkImage *image,
- gint *width,
- gint *height);
-static gboolean gail_image_set_image_description (AtkImage *image,
- const gchar *description);
-static void gail_image_finalize (GObject *object);
-
-G_DEFINE_TYPE_WITH_CODE (GailImage, gail_image, GAIL_TYPE_WIDGET,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init))
-
-static void
-gail_image_class_init (GailImageClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- gobject_class->finalize = gail_image_finalize;
- class->initialize = gail_image_initialize;
- class->get_name = gail_image_get_name;
-}
-
-static void
-gail_image_init (GailImage *image)
-{
- image->image_description = NULL;
-}
-
-static void
-gail_image_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_image_parent_class)->initialize (accessible, data);
-
- accessible->role = ATK_ROLE_ICON;
-}
-
-/* Copied from gtktoolbar.c, keep in sync */
-static gchar *
-elide_underscores (const gchar *original)
-{
- gchar *q, *result;
- const gchar *p, *end;
- gsize len;
- gboolean last_underscore;
-
- if (!original)
- return NULL;
-
- len = strlen (original);
- q = result = g_malloc (len + 1);
- last_underscore = FALSE;
-
- end = original + len;
- for (p = original; p < end; p++)
- {
- if (!last_underscore && *p == '_')
- last_underscore = TRUE;
- else
- {
- last_underscore = FALSE;
- if (original + 2 <= p && p + 1 <= end &&
- p[-2] == '(' && p[-1] == '_' && p[0] != '_' && p[1] == ')')
- {
- q--;
- *q = '\0';
- p++;
- }
- else
- *q++ = *p;
- }
- }
-
- if (last_underscore)
- *q++ = '_';
-
- *q = '\0';
-
- return result;
-}
-
-static const gchar*
-gail_image_get_name (AtkObject *accessible)
-{
- GtkWidget* widget;
- GtkImage *image;
- GailImage *image_accessible;
- GtkStockItem stock_item;
- gchar *stock_id;
- const gchar *name;
-
- name = ATK_OBJECT_CLASS (gail_image_parent_class)->get_name (accessible);
- if (name)
- return name;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- /*
- * State is defunct
- */
- if (widget == NULL)
- return NULL;
-
- g_return_val_if_fail (GTK_IS_IMAGE (widget), NULL);
- image = GTK_IMAGE (widget);
- image_accessible = GAIL_IMAGE (accessible);
-
- g_free (image_accessible->stock_name);
- image_accessible->stock_name = NULL;
-
- if (gtk_image_get_storage_type (image) != GTK_IMAGE_STOCK)
- return NULL;
-
- gtk_image_get_stock (image, &stock_id, NULL);
- if (stock_id == NULL)
- return NULL;
-
- if (!gtk_stock_lookup (stock_id, &stock_item))
- return NULL;
-
- image_accessible->stock_name = elide_underscores (stock_item.label);
- return image_accessible->stock_name;
-}
-
-static void
-atk_image_interface_init (AtkImageIface *iface)
-{
- iface->get_image_description = gail_image_get_image_description;
- iface->get_image_position = gail_image_get_image_position;
- iface->get_image_size = gail_image_get_image_size;
- iface->set_image_description = gail_image_set_image_description;
-}
-
-static const gchar *
-gail_image_get_image_description (AtkImage *image)
-{
- GailImage* aimage = GAIL_IMAGE (image);
-
- return aimage->image_description;
-}
-
-static void
-gail_image_get_image_position (AtkImage *image,
- gint *x,
- gint *y,
- AtkCoordType coord_type)
-{
- atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
-}
-
-static void
-gail_image_get_image_size (AtkImage *image,
- gint *width,
- gint *height)
-{
- GtkWidget* widget;
- GtkImage *gtk_image;
- GtkImageType image_type;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
- if (widget == 0)
- {
- /* State is defunct */
- *height = -1;
- *width = -1;
- return;
- }
-
- gtk_image = GTK_IMAGE(widget);
-
- image_type = gtk_image_get_storage_type(gtk_image);
-
- switch(image_type) {
- case GTK_IMAGE_PIXBUF:
- {
- GdkPixbuf *pixbuf;
- pixbuf = gtk_image_get_pixbuf(gtk_image);
- *height = gdk_pixbuf_get_height(pixbuf);
- *width = gdk_pixbuf_get_width(pixbuf);
- break;
- }
- case GTK_IMAGE_STOCK:
- case GTK_IMAGE_ICON_SET:
- case GTK_IMAGE_ICON_NAME:
- case GTK_IMAGE_GICON:
- {
- GtkIconSize size;
- GtkSettings *settings;
-
- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
-
- g_object_get (gtk_image, "icon-size", &size, NULL);
- gtk_icon_size_lookup_for_settings (settings, size, width, height);
- break;
- }
- case GTK_IMAGE_ANIMATION:
- {
- GdkPixbufAnimation *animation;
- animation = gtk_image_get_animation(gtk_image);
- *height = gdk_pixbuf_animation_get_height(animation);
- *width = gdk_pixbuf_animation_get_width(animation);
- break;
- }
- default:
- {
- *height = -1;
- *width = -1;
- break;
- }
- }
-}
-
-static gboolean
-gail_image_set_image_description (AtkImage *image,
- const gchar *description)
-{
- GailImage* aimage = GAIL_IMAGE (image);
-
- g_free (aimage->image_description);
- aimage->image_description = g_strdup (description);
- return TRUE;
-}
-
-static void
-gail_image_finalize (GObject *object)
-{
- GailImage *aimage = GAIL_IMAGE (object);
-
- g_free (aimage->image_description);
- g_free (aimage->stock_name);
-
- G_OBJECT_CLASS (gail_image_parent_class)->finalize (object);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_IMAGE_H__
-#define __GAIL_IMAGE_H__
-
-#include "gailwidget.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_IMAGE (gail_image_get_type ())
-#define GAIL_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_IMAGE, GailImage))
-#define GAIL_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_IMAGE, GailImageClass))
-#define GAIL_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_IMAGE))
-#define GAIL_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_IMAGE))
-#define GAIL_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_IMAGE, GailImageClass))
-
-typedef struct _GailImage GailImage;
-typedef struct _GailImageClass GailImageClass;
-
-struct _GailImage
-{
- GailWidget parent;
-
- gchar* image_description;
- gchar* stock_name;
-};
-
-GType gail_image_get_type (void);
-
-struct _GailImageClass
-{
- GailWidgetClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_IMAGE_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailimagecell.h"
-
-static void gail_image_cell_class_init (GailImageCellClass *klass);
-static void gail_image_cell_init (GailImageCell *image_cell);
-
-static void gail_image_cell_finalize (GObject *object);
-
-/* AtkImage */
-static void atk_image_interface_init (AtkImageIface *iface);
-static const gchar *
- gail_image_cell_get_image_description (AtkImage *image);
-static gboolean gail_image_cell_set_image_description (AtkImage *image,
- const gchar *description);
-static void gail_image_cell_get_image_position (AtkImage *image,
- gint *x,
- gint *y,
- AtkCoordType coord_type);
-static void gail_image_cell_get_image_size (AtkImage *image,
- gint *width,
- gint *height);
-
-/* Misc */
-
-static gboolean gail_image_cell_update_cache (GailRendererCell *cell,
- gboolean emit_change_signal);
-
-// FIXMEchpe static!!!
-gchar *gail_image_cell_property_list[] = {
- "pixbuf",
- NULL
-};
-
-G_DEFINE_TYPE_WITH_CODE (GailImageCell, gail_image_cell, GAIL_TYPE_RENDERER_CELL,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init))
-
-static void
-gail_image_cell_class_init (GailImageCellClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GailRendererCellClass *renderer_cell_class = GAIL_RENDERER_CELL_CLASS(klass);
-
- gobject_class->finalize = gail_image_cell_finalize;
-
- renderer_cell_class->update_cache = gail_image_cell_update_cache;
- renderer_cell_class->property_list = gail_image_cell_property_list;
-}
-
-AtkObject*
-gail_image_cell_new (void)
-{
- GObject *object;
- AtkObject *atk_object;
- GailRendererCell *cell;
-
- object = g_object_new (GAIL_TYPE_IMAGE_CELL, NULL);
-
- g_return_val_if_fail (object != NULL, NULL);
-
- atk_object = ATK_OBJECT (object);
- atk_object->role = ATK_ROLE_TABLE_CELL;
-
- cell = GAIL_RENDERER_CELL(object);
-
- cell->renderer = gtk_cell_renderer_pixbuf_new ();
- g_object_ref_sink (cell->renderer);
- return atk_object;
-}
-
-static void
-gail_image_cell_init (GailImageCell *image_cell)
-{
- image_cell->image_description = NULL;
-}
-
-
-static void
-gail_image_cell_finalize (GObject *object)
-{
- GailImageCell *image_cell = GAIL_IMAGE_CELL (object);
-
- g_free (image_cell->image_description);
- G_OBJECT_CLASS (gail_image_cell_parent_class)->finalize (object);
-}
-
-static gboolean
-gail_image_cell_update_cache (GailRendererCell *cell,
- gboolean emit_change_signal)
-{
- return FALSE;
-}
-
-static void
-atk_image_interface_init (AtkImageIface *iface)
-{
- iface->get_image_description = gail_image_cell_get_image_description;
- iface->set_image_description = gail_image_cell_set_image_description;
- iface->get_image_position = gail_image_cell_get_image_position;
- iface->get_image_size = gail_image_cell_get_image_size;
-}
-
-static const gchar *
-gail_image_cell_get_image_description (AtkImage *image)
-{
- GailImageCell *image_cell;
-
- image_cell = GAIL_IMAGE_CELL (image);
- return image_cell->image_description;
-}
-
-static gboolean
-gail_image_cell_set_image_description (AtkImage *image,
- const gchar *description)
-{
- GailImageCell *image_cell;
-
- image_cell = GAIL_IMAGE_CELL (image);
- g_free (image_cell->image_description);
- image_cell->image_description = g_strdup (description);
- if (image_cell->image_description)
- return TRUE;
- else
- return FALSE;
-}
-
-static void
-gail_image_cell_get_image_position (AtkImage *image,
- gint *x,
- gint *y,
- AtkCoordType coord_type)
-{
- atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
-}
-
-static void
-gail_image_cell_get_image_size (AtkImage *image,
- gint *width,
- gint *height)
-{
- GailImageCell *cell = GAIL_IMAGE_CELL (image);
- GtkCellRenderer *cell_renderer;
- GdkPixbuf *pixbuf;
-
- cell_renderer = GAIL_RENDERER_CELL (cell)->renderer;
- g_object_get (GTK_CELL_RENDERER_PIXBUF (cell_renderer), "pixbuf", &pixbuf, NULL);
-
- *width = gdk_pixbuf_get_width (pixbuf);
- *height = gdk_pixbuf_get_height (pixbuf);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_IMAGE_CELL_H__
-#define __GAIL_IMAGE_CELL_H__
-
-#include <atk/atk.h>
-#include "gailrenderercell.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_IMAGE_CELL (gail_image_cell_get_type ())
-#define GAIL_IMAGE_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_IMAGE_CELL, GailImageCell))
-#define GAIL_IMAGE_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_IMAGE_CELL, GailImageCellClass))
-#define GAIL_IS_IMAGE_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_IMAGE_CELL))
-#define GAIL_IS_IMAGE_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_IMAGE_CELL))78
-#define GAIL_IMAGE_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_IMAGE_CELL, GailImageCellClass))
-
-typedef struct _GailImageCell GailImageCell;
-typedef struct _GailImageCellClass GailImageCellClass;
-
-struct _GailImageCell
-{
- GailRendererCell parent;
-
- gchar *image_description;
- gint x, y;
-};
-
-GType gail_image_cell_get_type (void);
-
-struct _GailImageCellClass
-{
- GailRendererCellClass parent_class;
-};
-
-AtkObject *gail_image_cell_new (void);
-
-G_END_DECLS
-
-#endif /* __GAIL_TREE_VIEW_IMAGE_CELL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include "gaillabel.h"
-#include "gailwindow.h"
-#include <libgail-util/gailmisc.h>
-
-static void gail_label_class_init (GailLabelClass *klass);
-static void gail_label_init (GailLabel *label);
-static void gail_label_real_initialize (AtkObject *obj,
- gpointer data);
-static void gail_label_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-static void gail_label_map_gtk (GtkWidget *widget,
- gpointer data);
-static void gail_label_init_text_util (GailLabel *gail_label,
- GtkWidget *widget);
-static void gail_label_finalize (GObject *object);
-
-static void atk_text_interface_init (AtkTextIface *iface);
-
-/* atkobject.h */
-
-static const gchar* gail_label_get_name (AtkObject *accessible);
-static AtkStateSet* gail_label_ref_state_set (AtkObject *accessible);
-static AtkRelationSet* gail_label_ref_relation_set (AtkObject *accessible);
-
-/* atktext.h */
-
-static gchar* gail_label_get_text (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gunichar gail_label_get_character_at_offset(AtkText *text,
- gint offset);
-static gchar* gail_label_get_text_before_offset(AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_label_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_label_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gint gail_label_get_character_count (AtkText *text);
-static gint gail_label_get_caret_offset (AtkText *text);
-static gboolean gail_label_set_caret_offset (AtkText *text,
- gint offset);
-static gint gail_label_get_n_selections (AtkText *text);
-static gchar* gail_label_get_selection (AtkText *text,
- gint selection_num,
- gint *start_offset,
- gint *end_offset);
-static gboolean gail_label_add_selection (AtkText *text,
- gint start_offset,
- gint end_offset);
-static gboolean gail_label_remove_selection (AtkText *text,
- gint selection_num);
-static gboolean gail_label_set_selection (AtkText *text,
- gint selection_num,
- gint start_offset,
- gint end_offset);
-static void gail_label_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static gint gail_label_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static AtkAttributeSet* gail_label_get_run_attributes
- (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet* gail_label_get_default_attributes
- (AtkText *text);
-
-G_DEFINE_TYPE_WITH_CODE (GailLabel, gail_label, GAIL_TYPE_WIDGET,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
-
-static void
-gail_label_class_init (GailLabelClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailWidgetClass *widget_class;
-
- gobject_class->finalize = gail_label_finalize;
-
- widget_class = (GailWidgetClass*)klass;
- widget_class->notify_gtk = gail_label_real_notify_gtk;
-
- class->get_name = gail_label_get_name;
- class->ref_state_set = gail_label_ref_state_set;
- class->ref_relation_set = gail_label_ref_relation_set;
- class->initialize = gail_label_real_initialize;
-}
-
-static void
-gail_label_init (GailLabel *label)
-{
-}
-
-static void
-gail_label_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkWidget *widget;
- GailLabel *gail_label;
-
- ATK_OBJECT_CLASS (gail_label_parent_class)->initialize (obj, data);
-
- gail_label = GAIL_LABEL (obj);
-
- gail_label->window_create_handler = 0;
- gail_label->has_top_level = FALSE;
- gail_label->cursor_position = 0;
- gail_label->selection_bound = 0;
- gail_label->textutil = NULL;
- gail_label->label_length = 0;
-
- widget = GTK_WIDGET (data);
-
- if (gtk_widget_get_mapped (widget))
- gail_label_init_text_util (gail_label, widget);
- else
- g_signal_connect (widget,
- "map",
- G_CALLBACK (gail_label_map_gtk),
- gail_label);
-
- /*
- * Check whether ancestor of GtkLabel is a GtkButton and if so
- * set accessible parent for GailLabel
- */
- while (widget != NULL)
- {
- widget = gtk_widget_get_parent (widget);
- if (GTK_IS_BUTTON (widget))
- {
- atk_object_set_parent (obj, gtk_widget_get_accessible (widget));
- break;
- }
- }
-
- if (GTK_IS_ACCEL_LABEL (widget))
- obj->role = ATK_ROLE_ACCEL_LABEL;
- else
- obj->role = ATK_ROLE_LABEL;
-}
-
-static void
-gail_label_map_gtk (GtkWidget *widget,
- gpointer data)
-{
- GailLabel *gail_label;
-
- gail_label = GAIL_LABEL (data);
- gail_label_init_text_util (gail_label, widget);
-}
-
-static void
-gail_label_init_text_util (GailLabel *gail_label,
- GtkWidget *widget)
-{
- GtkLabel *label;
- const gchar *label_text;
-
- if (gail_label->textutil == NULL)
- gail_label->textutil = gail_text_util_new ();
-
- label = GTK_LABEL (widget);
- label_text = gtk_label_get_text (label);
- gail_text_util_text_setup (gail_label->textutil, label_text);
-
- if (label_text == NULL)
- gail_label->label_length = 0;
- else
- gail_label->label_length = g_utf8_strlen (label_text, -1);
-}
-
-static void
-notify_name_change (AtkObject *atk_obj)
-{
- GtkLabel *label;
- GailLabel *gail_label;
- GtkWidget *widget;
- GObject *gail_obj;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return;
-
- gail_obj = G_OBJECT (atk_obj);
- label = GTK_LABEL (widget);
- gail_label = GAIL_LABEL (atk_obj);
-
- if (gail_label->textutil == NULL)
- return;
-
- /*
- * Check whether the label has actually changed before emitting
- * notification.
- */
- if (gail_label->textutil->buffer)
- {
- GtkTextIter start, end;
- const char *new_label;
- char *old_label;
- int same;
-
- gtk_text_buffer_get_start_iter (gail_label->textutil->buffer, &start);
- gtk_text_buffer_get_end_iter (gail_label->textutil->buffer, &end);
- old_label = gtk_text_buffer_get_text (gail_label->textutil->buffer, &start, &end, FALSE);
- new_label = gtk_label_get_text (label);
- same = strcmp (new_label, old_label);
- g_free (old_label);
- if (same == 0)
- return;
- }
-
- /* Create a delete text and an insert text signal */
-
- g_signal_emit_by_name (gail_obj, "text_changed::delete", 0,
- gail_label->label_length);
-
- gail_label_init_text_util (gail_label, widget);
-
- g_signal_emit_by_name (gail_obj, "text_changed::insert", 0,
- gail_label->label_length);
-
- if (atk_obj->name == NULL)
- /*
- * The label has changed so notify a change in accessible-name
- */
- g_object_notify (gail_obj, "accessible-name");
-
- g_signal_emit_by_name (gail_obj, "visible_data_changed");
-}
-
-static void
-window_created (GObject *obj,
- gpointer data)
-{
- g_return_if_fail (GAIL_LABEL (data));
-
- notify_name_change (ATK_OBJECT (data));
-}
-
-static void
-gail_label_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkWidget *widget = GTK_WIDGET (obj);
- AtkObject* atk_obj = gtk_widget_get_accessible (widget);
- GtkLabel *label;
- GailLabel *gail_label;
- GObject *gail_obj;
- AtkObject *top_level;
- AtkObject *temp_obj;
-
- gail_label = GAIL_LABEL (atk_obj);
-
- if (strcmp (pspec->name, "label") == 0)
- {
- /*
- * We may get a label change for a label which is not attached to an
- * application. We wait until the toplevel window is created before
- * emitting the notification.
- *
- * This happens when [Ctrl+]Alt+Tab is pressed in metacity
- */
- if (!gail_label->has_top_level)
- {
- temp_obj = atk_obj;
- top_level = NULL;
- while (temp_obj)
- {
- top_level = temp_obj;
- temp_obj = atk_object_get_parent (top_level);
- }
- if (atk_object_get_role (top_level) != ATK_ROLE_APPLICATION)
- {
- if (gail_label->window_create_handler == 0 &&
- GAIL_IS_WINDOW (top_level))
- gail_label->window_create_handler = g_signal_connect_after (top_level, "create", G_CALLBACK (window_created), atk_obj);
- }
- else
- gail_label->has_top_level = TRUE;
- }
- if (gail_label->has_top_level)
- notify_name_change (atk_obj);
- }
- else if (strcmp (pspec->name, "cursor-position") == 0)
- {
- gint start, end, tmp;
- gboolean text_caret_moved = FALSE;
- gboolean selection_changed = FALSE;
-
- gail_obj = G_OBJECT (atk_obj);
- label = GTK_LABEL (widget);
-
- if (gail_label->selection_bound != -1 && gail_label->selection_bound < gail_label->cursor_position)
- {
- tmp = gail_label->selection_bound;
- gail_label->selection_bound = gail_label->cursor_position;
- gail_label->cursor_position = tmp;
- }
-
- if (gtk_label_get_selection_bounds (label, &start, &end))
- {
- if (start != gail_label->cursor_position ||
- end != gail_label->selection_bound)
- {
- if (end != gail_label->selection_bound)
- {
- gail_label->selection_bound = start;
- gail_label->cursor_position = end;
- }
- else
- {
- gail_label->selection_bound = end;
- gail_label->cursor_position = start;
- }
- text_caret_moved = TRUE;
- if (start != end)
- selection_changed = TRUE;
- }
- }
- else
- {
- if (gail_label->cursor_position != gail_label->selection_bound)
- selection_changed = TRUE;
- if (gtk_label_get_selectable (label))
- {
- if (gail_label->cursor_position != -1 && start != gail_label->cursor_position)
- text_caret_moved = TRUE;
- if (gail_label->selection_bound != -1 && end != gail_label->selection_bound)
- {
- text_caret_moved = TRUE;
- gail_label->cursor_position = end;
- gail_label->selection_bound = start;
- }
- else
- {
- gail_label->cursor_position = start;
- gail_label->selection_bound = end;
- }
- }
- else
- {
- /* GtkLabel has become non selectable */
-
- gail_label->cursor_position = 0;
- gail_label->selection_bound = 0;
- text_caret_moved = TRUE;
- }
-
- }
- if (text_caret_moved)
- g_signal_emit_by_name (gail_obj, "text_caret_moved",
- gail_label->cursor_position);
- if (selection_changed)
- g_signal_emit_by_name (gail_obj, "text_selection_changed");
-
- }
- else
- GAIL_WIDGET_CLASS (gail_label_parent_class)->notify_gtk (obj, pspec);
-}
-
-static void
-gail_label_finalize (GObject *object)
-{
- GailLabel *label = GAIL_LABEL (object);
-
- if (label->textutil)
- g_object_unref (label->textutil);
- G_OBJECT_CLASS (gail_label_parent_class)->finalize (object);
-}
-
-
-/* atkobject.h */
-
-static AtkStateSet*
-gail_label_ref_state_set (AtkObject *accessible)
-{
- AtkStateSet *state_set;
- GtkWidget *widget;
-
- state_set = ATK_OBJECT_CLASS (gail_label_parent_class)->ref_state_set (accessible);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- return state_set;
-
- atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
-
- return state_set;
-}
-
-AtkRelationSet*
-gail_label_ref_relation_set (AtkObject *obj)
-{
- GtkWidget *widget;
- AtkRelationSet *relation_set;
-
- g_return_val_if_fail (GAIL_IS_LABEL (obj), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- relation_set = ATK_OBJECT_CLASS (gail_label_parent_class)->ref_relation_set (obj);
-
- if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABEL_FOR))
- {
- /*
- * Get the mnemonic widget
- *
- * The relation set is not updated if the mnemonic widget is changed
- */
- GtkWidget *mnemonic_widget = gtk_label_get_mnemonic_widget (GTK_LABEL (widget));
-
- if (mnemonic_widget)
- {
- AtkObject *accessible_array[1];
- AtkRelation* relation;
-
- if (!gtk_widget_get_can_focus (mnemonic_widget))
- {
- /*
- * Handle the case where a GtkFileChooserButton is specified as the
- * mnemonic widget. use the combobox which is a child of the
- * GtkFileChooserButton as the mnemonic widget. See bug #359843.
- */
- if (GTK_IS_BOX (mnemonic_widget))
- {
- GList *list, *tmpl;
-
- list = gtk_container_get_children (GTK_CONTAINER (mnemonic_widget));
- if (g_list_length (list) == 2)
- {
- tmpl = g_list_last (list);
- if (GTK_IS_COMBO_BOX(tmpl->data))
- {
- mnemonic_widget = GTK_WIDGET(tmpl->data);
- }
- }
- g_list_free (list);
- }
- }
- accessible_array[0] = gtk_widget_get_accessible (mnemonic_widget);
- relation = atk_relation_new (accessible_array, 1,
- ATK_RELATION_LABEL_FOR);
- atk_relation_set_add (relation_set, relation);
- /*
- * Unref the relation so that it is not leaked.
- */
- g_object_unref (relation);
- }
- }
- return relation_set;
-}
-
-static const gchar*
-gail_label_get_name (AtkObject *accessible)
-{
- const gchar *name;
-
- g_return_val_if_fail (GAIL_IS_LABEL (accessible), NULL);
-
- name = ATK_OBJECT_CLASS (gail_label_parent_class)->get_name (accessible);
- if (name != NULL)
- return name;
- else
- {
- /*
- * Get the text on the label
- */
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- g_return_val_if_fail (GTK_IS_LABEL (widget), NULL);
-
- return gtk_label_get_text (GTK_LABEL (widget));
- }
-}
-
-/* atktext.h */
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_label_get_text;
- iface->get_character_at_offset = gail_label_get_character_at_offset;
- iface->get_text_before_offset = gail_label_get_text_before_offset;
- iface->get_text_at_offset = gail_label_get_text_at_offset;
- iface->get_text_after_offset = gail_label_get_text_after_offset;
- iface->get_character_count = gail_label_get_character_count;
- iface->get_caret_offset = gail_label_get_caret_offset;
- iface->set_caret_offset = gail_label_set_caret_offset;
- iface->get_n_selections = gail_label_get_n_selections;
- iface->get_selection = gail_label_get_selection;
- iface->add_selection = gail_label_add_selection;
- iface->remove_selection = gail_label_remove_selection;
- iface->set_selection = gail_label_set_selection;
- iface->get_character_extents = gail_label_get_character_extents;
- iface->get_offset_at_point = gail_label_get_offset_at_point;
- iface->get_run_attributes = gail_label_get_run_attributes;
- iface->get_default_attributes = gail_label_get_default_attributes;
-}
-
-static gchar*
-gail_label_get_text (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *widget;
- GtkLabel *label;
-
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = GTK_LABEL (widget);
-
- label_text = gtk_label_get_text (label);
-
- if (label_text == NULL)
- return NULL;
- else
- {
- if (GAIL_LABEL (text)->textutil == NULL)
- gail_label_init_text_util (GAIL_LABEL (text), widget);
- return gail_text_util_get_substring (GAIL_LABEL(text)->textutil,
- start_pos, end_pos);
- }
-}
-
-static gchar*
-gail_label_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkLabel *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get label */
- label = GTK_LABEL (widget);
-
- return gail_text_util_get_text (GAIL_LABEL (text)->textutil,
- gtk_label_get_layout (label), GAIL_BEFORE_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_label_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkLabel *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get label */
- label = GTK_LABEL (widget);
-
- return gail_text_util_get_text (GAIL_LABEL (text)->textutil,
- gtk_label_get_layout (label), GAIL_AT_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_label_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkLabel *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- {
- /* State is defunct */
- return NULL;
- }
-
- /* Get label */
- label = GTK_LABEL (widget);
-
- return gail_text_util_get_text (GAIL_LABEL (text)->textutil,
- gtk_label_get_layout (label), GAIL_AFTER_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gint
-gail_label_get_character_count (AtkText *text)
-{
- GtkWidget *widget;
- GtkLabel *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- label = GTK_LABEL (widget);
- return g_utf8_strlen (gtk_label_get_text (label), -1);
-}
-
-static gint
-gail_label_get_caret_offset (AtkText *text)
-{
- return GAIL_LABEL (text)->cursor_position;
-}
-
-static gboolean
-gail_label_set_caret_offset (AtkText *text,
- gint offset)
-{
- GtkWidget *widget;
- GtkLabel *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- label = GTK_LABEL (widget);
-
- if (gtk_label_get_selectable (label) &&
- offset >= 0 &&
- offset <= g_utf8_strlen (gtk_label_get_text (label), -1))
- {
- gtk_label_select_region (label, offset, offset);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gint
-gail_label_get_n_selections (AtkText *text)
-{
- GtkWidget *widget;
- GtkLabel *label;
- gint start, end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- label = GTK_LABEL (widget);
-
- if (!gtk_label_get_selectable (label))
- return 0;
-
- if (gtk_label_get_selection_bounds (label, &start, &end))
- return 1;
- else
- return 0;
-}
-
-static gchar*
-gail_label_get_selection (AtkText *text,
- gint selection_num,
- gint *start_pos,
- gint *end_pos)
-{
- GtkWidget *widget;
- GtkLabel *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = GTK_LABEL (widget);
-
- /* Only let the user get the selection if one is set, and if the
- * selection_num is 0.
- */
- if (!gtk_label_get_selectable( label) || selection_num != 0)
- return NULL;
-
- if (gtk_label_get_selection_bounds (label, start_pos, end_pos))
- {
- const gchar* label_text = gtk_label_get_text (label);
-
- if (label_text == NULL)
- return 0;
- else
- return gail_text_util_get_substring (GAIL_LABEL (text)->textutil,
- *start_pos, *end_pos);
- }
- else
- return NULL;
-}
-
-static gboolean
-gail_label_add_selection (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *widget;
- GtkLabel *label;
- gint start, end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- label = GTK_LABEL (widget);
-
- if (!gtk_label_get_selectable (label))
- return FALSE;
-
- if (! gtk_label_get_selection_bounds (label, &start, &end))
- {
- gtk_label_select_region (label, start_pos, end_pos);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gboolean
-gail_label_remove_selection (AtkText *text,
- gint selection_num)
-{
- GtkWidget *widget;
- GtkLabel *label;
- gint start, end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- if (selection_num != 0)
- return FALSE;
-
- label = GTK_LABEL (widget);
-
- if (!gtk_label_get_selectable (label))
- return FALSE;
-
- if (gtk_label_get_selection_bounds (label, &start, &end))
- {
- gtk_label_select_region (label, 0, 0);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gboolean
-gail_label_set_selection (AtkText *text,
- gint selection_num,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *widget;
- GtkLabel *label;
- gint start, end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- if (selection_num != 0)
- return FALSE;
-
- label = GTK_LABEL (widget);
-
- if (!gtk_label_get_selectable (label))
- return FALSE;
-
- if (gtk_label_get_selection_bounds (label, &start, &end))
- {
- gtk_label_select_region (label, start_pos, end_pos);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static void
-gail_label_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkLabel *label;
- PangoRectangle char_rect;
- const gchar *label_text;
- gint index, x_layout, y_layout;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return;
-
- label = GTK_LABEL (widget);
-
- gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
- label_text = gtk_label_get_text (label);
- index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
- pango_layout_index_to_pos (gtk_label_get_layout (label), index, &char_rect);
-
- gail_misc_get_extents_from_pango_rectangle (widget, &char_rect,
- x_layout, y_layout, x, y, width, height, coords);
-}
-
-static gint
-gail_label_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkLabel *label;
- const gchar *label_text;
- gint index, x_layout, y_layout;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return -1;
- label = GTK_LABEL (widget);
-
- gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
-
- index = gail_misc_get_index_at_point_in_layout (widget,
- gtk_label_get_layout (label),
- x_layout, y_layout, x, y, coords);
- label_text = gtk_label_get_text (label);
- if (index == -1)
- {
- if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
- return g_utf8_strlen (label_text, -1);
-
- return index;
- }
- else
- return g_utf8_pointer_to_offset (label_text, label_text + index);
-}
-
-static AtkAttributeSet*
-gail_label_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkLabel *label;
- AtkAttributeSet *at_set = NULL;
- GtkJustification justify;
- GtkTextDirection dir;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = GTK_LABEL (widget);
-
- /* Get values set for entire label, if any */
- justify = gtk_label_get_justify (label);
- if (justify != GTK_JUSTIFY_CENTER)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_JUSTIFICATION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
- }
- dir = gtk_widget_get_direction (widget);
- if (dir == GTK_TEXT_DIR_RTL)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_DIRECTION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
- }
-
- at_set = gail_misc_layout_get_run_attributes (at_set,
- gtk_label_get_layout (label),
- gtk_label_get_text (label),
- offset,
- start_offset,
- end_offset);
- return at_set;
-}
-
-static AtkAttributeSet*
-gail_label_get_default_attributes (AtkText *text)
-{
- GtkWidget *widget;
- GtkLabel *label;
- AtkAttributeSet *at_set = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = GTK_LABEL (widget);
-
- at_set = gail_misc_get_default_attributes (at_set,
- gtk_label_get_layout (label),
- widget);
- return at_set;
-}
-
-static gunichar
-gail_label_get_character_at_offset (AtkText *text,
- gint offset)
-{
- GtkWidget *widget;
- GtkLabel *label;
- const gchar *string;
- gchar *index;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return '\0';
-
- label = GTK_LABEL (widget);
- string = gtk_label_get_text (label);
- if (offset >= g_utf8_strlen (string, -1))
- return '\0';
- index = g_utf8_offset_to_pointer (string, offset);
-
- return g_utf8_get_char (index);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_LABEL_H__
-#define __GAIL_LABEL_H__
-
-#include "gailwidget.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_LABEL (gail_label_get_type ())
-#define GAIL_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_LABEL, GailLabel))
-#define GAIL_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_LABEL, GailLabelClass))
-#define GAIL_IS_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_LABEL))
-#define GAIL_IS_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_LABEL))
-#define GAIL_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_LABEL, GailLabelClass))
-
-typedef struct _GailLabel GailLabel;
-typedef struct _GailLabelClass GailLabelClass;
-
-struct _GailLabel
-{
- GailWidget parent;
-
- GailTextUtil *textutil;
- gint cursor_position;
- gint selection_bound;
- gint label_length;
- gulong window_create_handler;
- gboolean has_top_level;
-};
-
-GType gail_label_get_type (void);
-
-struct _GailLabelClass
-{
- GailWidgetClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_LABEL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2011 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gaillinkbutton.h"
-
-typedef struct _GailLinkButtonLink GailLinkButtonLink;
-typedef struct _GailLinkButtonLinkClass GailLinkButtonLinkClass;
-
-struct _GailLinkButtonLink
-{
- AtkHyperlink parent;
-
- GailLinkButton *button;
- gchar *description;
-};
-
-struct _GailLinkButtonLinkClass
-{
- AtkHyperlinkClass parent_class;
-};
-
-static void atk_action_interface_init (AtkActionIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GailLinkButtonLink, gail_link_button_link, ATK_TYPE_HYPERLINK,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
-
-static gchar *
-gail_link_button_link_get_uri (AtkHyperlink *link,
- gint i)
-{
- GailLinkButtonLink *l = (GailLinkButtonLink *)link;
- GtkWidget *widget;
- const gchar *uri;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (l->button));
- uri = gtk_link_button_get_uri (GTK_LINK_BUTTON (widget));
-
- return g_strdup (uri);
-}
-
-static gint
-gail_link_button_link_get_n_anchors (AtkHyperlink *link)
-{
- return 1;
-}
-
-static gboolean
-gail_link_button_link_is_valid (AtkHyperlink *link)
-{
- return TRUE;
-}
-
-static AtkObject *
-gail_link_button_link_get_object (AtkHyperlink *link,
- gint i)
-{
- GailLinkButtonLink *l = (GailLinkButtonLink *)link;
-
- return ATK_OBJECT (l->button);
-}
-
-static gint
-gail_link_button_link_get_start_index (AtkHyperlink *link)
-{
- return 0;
-}
-
-static gint
-gail_link_button_link_get_end_index (AtkHyperlink *link)
-{
- GailLinkButtonLink *l = (GailLinkButtonLink *)link;
-
- return atk_text_get_character_count (ATK_TEXT (l->button));
-}
-
-static void
-gail_link_button_link_init (GailLinkButtonLink *link)
-{
- link->description = NULL;
-}
-
-static void
-gail_link_button_link_finalize (GObject *obj)
-{
- GailLinkButtonLink *link = (GailLinkButtonLink *)obj;
-
- g_free (link->description);
-
- G_OBJECT_CLASS (gail_link_button_link_parent_class)->finalize (obj);
-}
-
-static void
-gail_link_button_link_class_init (GailLinkButtonLinkClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- AtkHyperlinkClass *hyperlink_class = ATK_HYPERLINK_CLASS (class);
-
- object_class->finalize = gail_link_button_link_finalize;
-
- hyperlink_class->get_uri = gail_link_button_link_get_uri;
- hyperlink_class->get_n_anchors = gail_link_button_link_get_n_anchors;
- hyperlink_class->is_valid = gail_link_button_link_is_valid;
- hyperlink_class->get_object = gail_link_button_link_get_object;
- hyperlink_class->get_start_index = gail_link_button_link_get_start_index;
- hyperlink_class->get_end_index = gail_link_button_link_get_end_index;
-}
-
-static gboolean
-gail_link_button_link_do_action (AtkAction *action,
- gint i)
-{
- GailLinkButtonLink *link = (GailLinkButtonLink *)action;
- GtkWidget *widget;
-
- widget = GTK_WIDGET (link->button);
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- gtk_button_clicked (GTK_BUTTON (widget));
-
- return TRUE;
-}
-
-static gint
-gail_link_button_link_get_n_actions (AtkAction *action)
-{
- return 1;
-}
-
-static const gchar *
-gail_link_button_link_get_name (AtkAction *action,
- gint i)
-{
- g_return_val_if_fail (i == 0, NULL);
-
- return "activate";
-}
-
-static const gchar *
-gail_link_button_link_get_description (AtkAction *action,
- gint i)
-{
- GailLinkButtonLink *link = (GailLinkButtonLink *)action;
-
- g_return_val_if_fail (i == 0, NULL);
-
- return link->description;
-}
-
-static gboolean
-gail_link_button_link_set_description (AtkAction *action,
- gint i,
- const gchar *description)
-{
- GailLinkButtonLink *link = (GailLinkButtonLink *)action;
-
- g_return_val_if_fail (i == 0, FALSE);
-
- g_free (link->description);
- link->description = g_strdup (description);
-
- return TRUE;
-}
-
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- iface->do_action = gail_link_button_link_do_action;
- iface->get_n_actions = gail_link_button_link_get_n_actions;
- iface->get_name = gail_link_button_link_get_name;
- iface->get_description = gail_link_button_link_get_description;
- iface->set_description = gail_link_button_link_set_description;
-}
-
-static gboolean
-activate_link (GtkLinkButton *button, AtkHyperlink *link)
-{
- g_signal_emit_by_name (link, "link-activated");
-
- return FALSE;
-}
-
-static AtkHyperlink *
-gail_link_button_get_hyperlink (AtkHyperlinkImpl *impl)
-{
- GailLinkButton *button = GAIL_LINK_BUTTON (impl);
-
- if (!button->link)
- {
- button->link = g_object_new (gail_link_button_link_get_type (), NULL);
- g_signal_connect (gtk_accessible_get_widget (GTK_ACCESSIBLE (button)),
- "activate-link", G_CALLBACK (activate_link), button->link);
- }
-
- return button->link;
-}
-
-static void atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GailLinkButton, gail_link_button, GAIL_TYPE_BUTTON,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERLINK_IMPL, atk_hypertext_impl_interface_init))
-
-static void
-gail_link_button_init (GailLinkButton *button)
-{
-}
-
-static void
-gail_link_button_finalize (GObject *object)
-{
- GailLinkButton *button = GAIL_LINK_BUTTON (object);
-
- if (button->link)
- g_object_unref (button->link);
-
- G_OBJECT_CLASS (gail_link_button_parent_class)->finalize (object);
-}
-
-static void
-gail_link_button_class_init (GailLinkButtonClass *klass)
-{
- G_OBJECT_CLASS (klass)->finalize = gail_link_button_finalize;
-}
-
-static void
-atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface)
-{
- iface->get_hyperlink = gail_link_button_get_hyperlink;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2011 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_LINK_BUTTON_H__
-#define __GAIL_LINK_BUTTON_H__
-
-#include "gailbutton.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_LINK_BUTTON (gail_link_button_get_type ())
-#define GAIL_LINK_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_LINK_BUTTON, GailLinkButton))
-#define GAIL_LINK_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_LINK_BUTTON, GailLinkButtonClass))
-#define GAIL_IS_LINK_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_LINK_BUTTON))
-#define GAIL_IS_LINK_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_LINK_BUTTON))
-#define GAIL_LINK_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_LINK_BUTTON, GailLinkButtonClass))
-
-typedef struct _GailLinkButton GailLinkButton;
-typedef struct _GailLinkButtonClass GailLinkButtonClass;
-
-struct _GailLinkButton
-{
- GailButton parent;
-
- AtkHyperlink *link;
-};
-
-GType gail_link_button_get_type (void);
-
-struct _GailLinkButtonClass
-{
- GailButtonClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_LINK_BUTTON_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gailmenu.h"
-
-static void gail_menu_class_init (GailMenuClass *klass);
-static void gail_menu_init (GailMenu *accessible);
-
-static void gail_menu_real_initialize (AtkObject *obj,
- gpointer data);
-
-static AtkObject* gail_menu_get_parent (AtkObject *accessible);
-static gint gail_menu_get_index_in_parent (AtkObject *accessible);
-
-G_DEFINE_TYPE (GailMenu, gail_menu, GAIL_TYPE_MENU_SHELL)
-
-static void
-gail_menu_class_init (GailMenuClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->get_parent = gail_menu_get_parent;
- class->get_index_in_parent = gail_menu_get_index_in_parent;
- class->initialize = gail_menu_real_initialize;
-}
-
-static void
-gail_menu_init (GailMenu *accessible)
-{
-}
-
-static void
-gail_menu_real_initialize (AtkObject *obj,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_menu_parent_class)->initialize (obj, data);
-
- obj->role = ATK_ROLE_MENU;
-
- g_object_set_data (G_OBJECT (obj), "atk-component-layer",
- GINT_TO_POINTER (ATK_LAYER_POPUP));
-}
-
-static AtkObject*
-gail_menu_get_parent (AtkObject *accessible)
-{
- AtkObject *parent;
-
- parent = accessible->accessible_parent;
-
- if (parent != NULL)
- {
- g_return_val_if_fail (ATK_IS_OBJECT (parent), NULL);
- }
- else
- {
- GtkWidget *widget, *parent_widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- if (widget == NULL)
- {
- /*
- * State is defunct
- */
- return NULL;
- }
- g_return_val_if_fail (GTK_IS_MENU (widget), NULL);
-
- /*
- * If the menu is attached to a menu item or a button (Gnome Menu)
- * report the menu item as parent.
- */
- parent_widget = gtk_menu_get_attach_widget (GTK_MENU (widget));
-
- if (!GTK_IS_MENU_ITEM (parent_widget) && !GTK_IS_BUTTON (parent_widget) && !GTK_IS_COMBO_BOX (parent_widget))
- parent_widget = gtk_widget_get_parent (widget);
-
- if (parent_widget == NULL)
- return NULL;
-
- parent = gtk_widget_get_accessible (parent_widget);
- atk_object_set_parent (accessible, parent);
- }
- return parent;
-}
-
-static gint
-gail_menu_get_index_in_parent (AtkObject *accessible)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- {
- /*
- * State is defunct
- */
- return -1;
- }
- g_return_val_if_fail (GTK_IS_MENU (widget), -1);
-
- if (gtk_menu_get_attach_widget (GTK_MENU (widget)))
- {
- return 0;
- }
- return ATK_OBJECT_CLASS (gail_menu_parent_class)->get_index_in_parent (accessible);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_MENU_H__
-#define __GAIL_MENU_H__
-
-#include "gailmenushell.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_MENU (gail_menu_get_type ())
-#define GAIL_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_MENU_SHELL, GailMenu))
-#define GAIL_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_MENU, GailMenuClass))
-#define GAIL_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_MENU))
-#define GAIL_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_MENU))
-#define GAIL_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_MENU, GailMenuClass))
-
-typedef struct _GailMenu GailMenu;
-typedef struct _GailMenuClass GailMenuClass;
-
-struct _GailMenu
-{
- GailMenuShell parent;
-};
-
-GType gail_menu_get_type (void);
-
-struct _GailMenuClass
-{
- GailMenuShellClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_MENU_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "gailmenuitem.h"
-#include "gailsubmenuitem.h"
-#include <libgail-util/gailmisc.h>
-
-#define KEYBINDING_SEPARATOR ";"
-
-static void gail_menu_item_class_init (GailMenuItemClass *klass);
-static void gail_menu_item_init (GailMenuItem *menu_item);
-
-static void gail_menu_item_real_initialize
- (AtkObject *obj,
- gpointer data);
-static gint gail_menu_item_get_n_children (AtkObject *obj);
-static AtkObject* gail_menu_item_ref_child (AtkObject *obj,
- gint i);
-static AtkStateSet* gail_menu_item_ref_state_set (AtkObject *obj);
-static void gail_menu_item_finalize (GObject *object);
-static void gail_menu_item_label_map_gtk (GtkWidget *widget,
- gpointer data);
-static void gail_menu_item_init_textutil (GailMenuItem *item,
- GtkWidget *label);
-static void gail_menu_item_notify_label_gtk (GObject *obj,
- GParamSpec *pspec,
- gpointer data);
-static const gchar * gail_menu_item_get_name (AtkObject *object);
-
-
-static void atk_action_interface_init (AtkActionIface *iface);
-static gboolean gail_menu_item_do_action (AtkAction *action,
- gint i);
-static gboolean idle_do_action (gpointer data);
-static gint gail_menu_item_get_n_actions (AtkAction *action);
-static const gchar* gail_menu_item_get_description(AtkAction *action,
- gint i);
-static const gchar* gail_menu_item_action_get_name (AtkAction *action,
- gint i);
-static const gchar* gail_menu_item_get_keybinding (AtkAction *action,
- gint i);
-static gboolean gail_menu_item_set_description(AtkAction *action,
- gint i,
- const gchar *desc);
-static void menu_item_select (GtkMenuItem *item);
-static void menu_item_deselect (GtkMenuItem *item);
-static void menu_item_selection (GtkMenuItem *item,
- gboolean selected);
-static gboolean find_accel (GtkAccelKey *key,
- GClosure *closure,
- gpointer data);
-static gboolean find_accel_new (GtkAccelKey *key,
- GClosure *closure,
- gpointer data);
-/* atktext.h */
-static void atk_text_interface_init (AtkTextIface *iface);
-
-static gchar* gail_menu_item_get_text (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gunichar gail_menu_item_get_character_at_offset (AtkText *text,
- gint offset);
-static gchar* gail_menu_item_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_menu_item_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_menu_item_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gint gail_menu_item_get_character_count (AtkText *text);
-static void gail_menu_item_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static gint gail_menu_item_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static AtkAttributeSet* gail_menu_item_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet* gail_menu_item_get_default_attributes (AtkText *text);
-static GtkWidget* get_label_from_container (GtkWidget *container);
-static gchar * get_text_from_label_widget (GtkWidget *widget);
-
-
-G_DEFINE_TYPE_WITH_CODE (GailMenuItem, gail_menu_item, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
-
-static void
-gail_menu_item_class_init (GailMenuItemClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- gobject_class->finalize = gail_menu_item_finalize;
-
- class->get_n_children = gail_menu_item_get_n_children;
- class->ref_child = gail_menu_item_ref_child;
- class->ref_state_set = gail_menu_item_ref_state_set;
- class->initialize = gail_menu_item_real_initialize;
- class->get_name = gail_menu_item_get_name;
-}
-
-static void
-gail_menu_item_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkWidget *widget;
- GtkWidget *parent;
- GailMenuItem *item = GAIL_MENU_ITEM (obj);
- GtkWidget *label;
-
- ATK_OBJECT_CLASS (gail_menu_item_parent_class)->initialize (obj, data);
-
- item->textutil = NULL;
- item->text = NULL;
-
- label = get_label_from_container (GTK_WIDGET (data));
- if (gtk_widget_get_mapped (label))
- gail_menu_item_init_textutil (item, label);
- else
- g_signal_connect (label,
- "map",
- G_CALLBACK (gail_menu_item_label_map_gtk),
- item);
-
- g_signal_connect (data,
- "select",
- G_CALLBACK (menu_item_select),
- NULL);
- g_signal_connect (data,
- "deselect",
- G_CALLBACK (menu_item_deselect),
- NULL);
- widget = GTK_WIDGET (data);
- parent = gtk_widget_get_parent (widget);
- if (GTK_IS_MENU (parent))
- {
- GtkWidget *parent_widget;
-
- parent_widget = gtk_menu_get_attach_widget (GTK_MENU (parent));
-
- if (!GTK_IS_MENU_ITEM (parent_widget))
- parent_widget = gtk_widget_get_parent (widget);
- if (parent_widget)
- {
- atk_object_set_parent (obj, gtk_widget_get_accessible (parent_widget));
- }
- }
- g_object_set_data (G_OBJECT (obj), "atk-component-layer",
- GINT_TO_POINTER (ATK_LAYER_POPUP));
-
- if (GTK_IS_TEAROFF_MENU_ITEM (data))
- obj->role = ATK_ROLE_TEAR_OFF_MENU_ITEM;
- else if (GTK_IS_SEPARATOR_MENU_ITEM (data))
- obj->role = ATK_ROLE_SEPARATOR;
- else
- obj->role = ATK_ROLE_MENU_ITEM;
-}
-
-static void
-gail_menu_item_init (GailMenuItem *menu_item)
-{
- menu_item->click_keybinding = NULL;
- menu_item->click_description = NULL;
-}
-
-static void
-gail_menu_item_label_map_gtk (GtkWidget *widget,
- gpointer data)
-{
- GailMenuItem *item;
-
- item = GAIL_MENU_ITEM (data);
- gail_menu_item_init_textutil (item, widget);
-}
-
-static void
-gail_menu_item_notify_label_gtk (GObject *obj,
- GParamSpec *pspec,
- gpointer data)
-{
- AtkObject* atk_obj = ATK_OBJECT (data);
- GtkLabel *label;
- GailMenuItem *menu_item;
-
- if (strcmp (pspec->name, "label") == 0)
- {
- const gchar* label_text;
-
- label = GTK_LABEL (obj);
-
- label_text = gtk_label_get_text (label);
-
- menu_item = GAIL_MENU_ITEM (atk_obj);
- gail_text_util_text_setup (menu_item->textutil, label_text);
-
- if (atk_obj->name == NULL)
- {
- /*
- * The label has changed so notify a change in accessible-name
- */
- g_object_notify (G_OBJECT (atk_obj), "accessible-name");
- }
- /*
- * The label is the only property which can be changed
- */
- g_signal_emit_by_name (atk_obj, "visible_data_changed");
- }
-}
-
-static void
-gail_menu_item_init_textutil (GailMenuItem *item,
- GtkWidget *label)
-{
- const gchar *label_text;
-
- if (item->textutil == NULL)
- {
- item->textutil = gail_text_util_new ();
- g_signal_connect (label,
- "notify",
- (GCallback) gail_menu_item_notify_label_gtk,
- item);
- }
- label_text = get_text_from_label_widget (label);
- gail_text_util_text_setup (item->textutil, label_text);
-}
-
-/* atktext.h */
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_menu_item_get_text;
- iface->get_character_at_offset = gail_menu_item_get_character_at_offset;
- iface->get_text_before_offset = gail_menu_item_get_text_before_offset;
- iface->get_text_at_offset = gail_menu_item_get_text_at_offset;
- iface->get_text_after_offset = gail_menu_item_get_text_after_offset;
- iface->get_character_count = gail_menu_item_get_character_count;
- iface->get_character_extents = gail_menu_item_get_character_extents;
- iface->get_offset_at_point = gail_menu_item_get_offset_at_point;
- iface->get_run_attributes = gail_menu_item_get_run_attributes;
- iface->get_default_attributes = gail_menu_item_get_default_attributes;
-}
-
-static gchar*
-gail_menu_item_get_text (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailMenuItem *item;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = get_label_from_container (widget);
-
- item = GAIL_MENU_ITEM (text);
- if (!item->textutil)
- gail_menu_item_init_textutil (item, label);
-
- label_text = get_text_from_label_widget (label);
-
- if (label_text == NULL)
- return NULL;
- else
- return gail_text_util_get_substring (item->textutil,
- start_pos, end_pos);
-}
-
-static gchar*
-gail_menu_item_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailMenuItem *item;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get label */
- label = get_label_from_container (widget);
-
- item = GAIL_MENU_ITEM (text);
- if (!item->textutil)
- gail_menu_item_init_textutil (item, label);
-
- return gail_text_util_get_text (item->textutil,
- NULL, GAIL_BEFORE_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_menu_item_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailMenuItem *item;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get label */
- label = get_label_from_container (widget);
-
- item = GAIL_MENU_ITEM (text);
- if (!item->textutil)
- gail_menu_item_init_textutil (item, label);
-
- return gail_text_util_get_text (item->textutil,
- NULL, GAIL_AT_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_menu_item_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailMenuItem *item;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- {
- /* State is defunct */
- return NULL;
- }
-
- /* Get label */
- label = get_label_from_container (widget);
-
- item = GAIL_MENU_ITEM (text);
- if (!item->textutil)
- gail_menu_item_init_textutil (item, label);
-
- return gail_text_util_get_text (item->textutil,
- NULL, GAIL_AFTER_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gint
-gail_menu_item_get_character_count (AtkText *atk_text)
-{
- gchar *text;
- gint len;
-
- text = gail_menu_item_get_text (atk_text, 0, -1);
- if (text)
- {
- len = g_utf8_strlen (text, -1);
- g_free (text);
- }
- else
- len = 0;
-
- return len;
-}
-
-static void
-gail_menu_item_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkWidget *label;
- PangoRectangle char_rect;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return;
-
- label = get_label_from_container (widget);
-
- if (!GTK_IS_LABEL(label))
- return;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
- pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
-
- gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
- x_layout, y_layout, x, y, width, height, coords);
-}
-
-static gint
-gail_menu_item_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkWidget *label;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- label = get_label_from_container (widget);
-
- if (!GTK_IS_LABEL(label))
- return -1;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
-
- index = gail_misc_get_index_at_point_in_layout (label,
- gtk_label_get_layout (GTK_LABEL (label)),
- x_layout, y_layout, x, y, coords);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- if (index == -1)
- {
- if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
- return g_utf8_strlen (label_text, -1);
-
- return index;
- }
- else
- return g_utf8_pointer_to_offset (label_text, label_text + index);
-}
-
-static AtkAttributeSet*
-gail_menu_item_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- AtkAttributeSet *at_set = NULL;
- GtkJustification justify;
- GtkTextDirection dir;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = get_label_from_container (widget);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- /* Get values set for entire label, if any */
- justify = gtk_label_get_justify (GTK_LABEL (label));
- if (justify != GTK_JUSTIFY_CENTER)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_JUSTIFICATION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
- }
- dir = gtk_widget_get_direction (label);
- if (dir == GTK_TEXT_DIR_RTL)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_DIRECTION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
- }
-
- at_set = gail_misc_layout_get_run_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- (gchar *) gtk_label_get_text (GTK_LABEL (label)),
- offset,
- start_offset,
- end_offset);
- return at_set;
-}
-
-static AtkAttributeSet*
-gail_menu_item_get_default_attributes (AtkText *text)
-{
- GtkWidget *widget;
- GtkWidget *label;
- AtkAttributeSet *at_set = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = get_label_from_container (widget);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- at_set = gail_misc_get_default_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- widget);
- return at_set;
-}
-
-static gunichar
-gail_menu_item_get_character_at_offset (AtkText *text,
- gint offset)
-{
- gchar *string;
- gchar *index;
- gunichar ch;
-
- string = gail_menu_item_get_text (text, 0, -1);
-
- if (string == NULL || offset >= g_utf8_strlen (string, -1))
- ch = '\0';
- else
- {
- index = g_utf8_offset_to_pointer (string, offset);
- ch = g_utf8_get_char (index);
- }
-
- g_free (string);
-
- return ch;
-}
-
-static GtkWidget*
-get_label_from_container (GtkWidget *container)
-{
- GtkWidget *label;
- GList *children, *tmp_list;
-
- if (!GTK_IS_CONTAINER (container))
- return NULL;
-
- children = gtk_container_get_children (GTK_CONTAINER (container));
- label = NULL;
-
- for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
- {
- if (GTK_IS_LABEL (tmp_list->data))
- {
- label = tmp_list->data;
- break;
- }
- else if (GTK_IS_CELL_VIEW (tmp_list->data))
- {
- label = tmp_list->data;
- break;
- }
- /*
- * * Get label from menu item in desktop background preferences
- * * option menu. See bug #144084.
- * */
- else if (GTK_IS_BOX (tmp_list->data))
- {
- label = get_label_from_container (GTK_WIDGET (tmp_list->data));
- if (label)
- break;
- }
- }
- g_list_free (children);
-
- return label;
-}
-
-static gchar *
-get_text_from_label_widget (GtkWidget *label)
-{
- if (GTK_IS_LABEL (label))
- return g_strdup (gtk_label_get_text (GTK_LABEL (label)));
- else if (GTK_IS_CELL_VIEW (label))
- {
- GList *cells, *l;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkTreePath *path;
- GtkCellArea *area;
- gchar *text;
-
- model = gtk_cell_view_get_model (GTK_CELL_VIEW (label));
- path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (label));
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
-
- area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (label));
-
- gtk_cell_area_apply_attributes (area, model, &iter, FALSE, FALSE);
-
- cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (label));
- for (l = cells; l; l = l->next)
- {
- GtkCellRenderer *cell = l->data;
-
- if (GTK_IS_CELL_RENDERER_TEXT (cell))
- {
- g_object_get (cell, "text", &text, NULL);
- break;
- }
- }
-
- g_list_free (cells);
-
- return text;
- }
-
- return NULL;
-}
-
-AtkObject*
-gail_menu_item_new (GtkWidget *widget)
-{
- GObject *object;
- AtkObject *accessible;
-
- g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), NULL);
-
- if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)))
- return gail_sub_menu_item_new (widget);
-
- object = g_object_new (GAIL_TYPE_MENU_ITEM, NULL);
-
- accessible = ATK_OBJECT (object);
- atk_object_initialize (accessible, widget);
-
- return accessible;
-}
-
-GList *
-get_children (GtkWidget *submenu)
-{
- GList *children;
-
- children = gtk_container_get_children (GTK_CONTAINER (submenu));
- if (g_list_length (children) == 0)
- {
- /*
- * If menu is empty it may be because the menu items are created only
- * on demand. For example, in gnome-panel the menu items are created
- * only when "show" signal is emitted on the menu.
- *
- * The following hack forces the menu items to be created.
- */
- if (!gtk_widget_get_visible (submenu))
- {
- /* FIXME GTK_WIDGET_SET_FLAGS (submenu, GTK_VISIBLE); */
- g_signal_emit_by_name (submenu, "show");
- /* FIXME GTK_WIDGET_UNSET_FLAGS (submenu, GTK_VISIBLE); */
- }
- g_list_free (children);
- children = gtk_container_get_children (GTK_CONTAINER (submenu));
- }
- return children;
-}
-
-/*
- * If a menu item has a submenu return the items of the submenu as the
- * accessible children; otherwise expose no accessible children.
- */
-static gint
-gail_menu_item_get_n_children (AtkObject* obj)
-{
- GtkWidget *widget;
- GtkWidget *submenu;
- gint count = 0;
-
- g_return_val_if_fail (GAIL_IS_MENU_ITEM (obj), count);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return count;
-
- submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
- if (submenu)
- {
- GList *children;
-
- children = get_children (submenu);
- count = g_list_length (children);
- g_list_free (children);
- }
- return count;
-}
-
-static AtkObject*
-gail_menu_item_ref_child (AtkObject *obj,
- gint i)
-{
- AtkObject *accessible;
- GtkWidget *widget;
- GtkWidget *submenu;
-
- g_return_val_if_fail (GAIL_IS_MENU_ITEM (obj), NULL);
- g_return_val_if_fail ((i >= 0), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return NULL;
-
- submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
- if (submenu)
- {
- GList *children;
- GList *tmp_list;
-
- children = get_children (submenu);
- tmp_list = g_list_nth (children, i);
- if (!tmp_list)
- {
- g_list_free (children);
- return NULL;
- }
- accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
- g_list_free (children);
- g_object_ref (accessible);
- }
- else
- accessible = NULL;
-
- return accessible;
-}
-
-static AtkStateSet*
-gail_menu_item_ref_state_set (AtkObject *obj)
-{
- AtkObject *menu_item;
- AtkStateSet *state_set, *parent_state_set;
-
- state_set = ATK_OBJECT_CLASS (gail_menu_item_parent_class)->ref_state_set (obj);
-
- menu_item = atk_object_get_parent (obj);
-
- if (menu_item)
- {
- if (!GTK_IS_MENU_ITEM (gtk_accessible_get_widget (GTK_ACCESSIBLE (menu_item))))
- return state_set;
-
- parent_state_set = atk_object_ref_state_set (menu_item);
- if (!atk_state_set_contains_state (parent_state_set, ATK_STATE_SELECTED))
- {
- atk_state_set_remove_state (state_set, ATK_STATE_FOCUSED);
- atk_state_set_remove_state (state_set, ATK_STATE_SHOWING);
- }
- }
- return state_set;
-}
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- iface->do_action = gail_menu_item_do_action;
- iface->get_n_actions = gail_menu_item_get_n_actions;
- iface->get_description = gail_menu_item_get_description;
- iface->get_name = gail_menu_item_action_get_name;
- iface->get_keybinding = gail_menu_item_get_keybinding;
- iface->set_description = gail_menu_item_set_description;
-}
-
-static gboolean
-gail_menu_item_do_action (AtkAction *action,
- gint i)
-{
- if (i == 0)
- {
- GtkWidget *item;
- GailMenuItem *gail_menu_item;
-
- item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
- if (item == NULL)
- /* State is defunct */
- return FALSE;
-
- if (!gtk_widget_get_sensitive (item) || !gtk_widget_get_visible (item))
- return FALSE;
-
- gail_menu_item = GAIL_MENU_ITEM (action);
- if (gail_menu_item->action_idle_handler)
- return FALSE;
- else
- {
- gail_menu_item->action_idle_handler =
- gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE,
- idle_do_action,
- g_object_ref (gail_menu_item),
- (GDestroyNotify) g_object_unref);
- }
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static void
-ensure_menus_unposted (GailMenuItem *menu_item)
-{
- AtkObject *parent;
- GtkWidget *widget;
-
- parent = atk_object_get_parent (ATK_OBJECT (menu_item));
- while (parent)
- {
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
- if (GTK_IS_MENU (widget))
- {
- if (gtk_widget_get_mapped (widget))
- gtk_menu_shell_cancel (GTK_MENU_SHELL (widget));
-
- return;
- }
- parent = atk_object_get_parent (parent);
- }
-}
-
-static gboolean
-idle_do_action (gpointer data)
-{
- GtkWidget *item;
- GtkWidget *item_parent;
- GailMenuItem *menu_item;
- gboolean item_mapped;
-
- menu_item = GAIL_MENU_ITEM (data);
- menu_item->action_idle_handler = 0;
- item = gtk_accessible_get_widget (GTK_ACCESSIBLE (menu_item));
- if (item == NULL /* State is defunct */ ||
- !gtk_widget_get_sensitive (item) || !gtk_widget_get_visible (item))
- return FALSE;
-
- item_parent = gtk_widget_get_parent (item);
- gtk_menu_shell_select_item (GTK_MENU_SHELL (item_parent), item);
- item_mapped = gtk_widget_get_mapped (item);
- /*
- * This is what is called when <Return> is pressed for a menu item
- */
- g_signal_emit_by_name (item_parent, "activate_current",
- /*force_hide*/ 1);
- if (!item_mapped)
- ensure_menus_unposted (menu_item);
-
- return FALSE;
-}
-
-static gint
-gail_menu_item_get_n_actions (AtkAction *action)
-{
- /*
- * Menu item has 1 action
- */
- return 1;
-}
-
-static const gchar*
-gail_menu_item_get_description (AtkAction *action,
- gint i)
-{
- if (i == 0)
- {
- GailMenuItem *item;
-
- item = GAIL_MENU_ITEM (action);
- return item->click_description;
- }
- else
- return NULL;
-}
-
-static const gchar*
-gail_menu_item_action_get_name (AtkAction *action,
- gint i)
-{
- if (i == 0)
- return "click";
- else
- return NULL;
-}
-
-static const gchar*
-gail_menu_item_get_keybinding (AtkAction *action,
- gint i)
-{
- /*
- * This function returns a string of the form A;B;C where
- * A is the keybinding for the widget; B is the keybinding to traverse
- * from the menubar and C is the accelerator.
- * The items in the keybinding to traverse from the menubar are separated
- * by ":".
- */
- GailMenuItem *gail_menu_item;
- gchar *keybinding = NULL;
- gchar *item_keybinding = NULL;
- gchar *full_keybinding = NULL;
- gchar *accelerator = NULL;
-
- gail_menu_item = GAIL_MENU_ITEM (action);
- if (i == 0)
- {
- GtkWidget *item;
- GtkWidget *temp_item;
- GtkWidget *child;
- GtkWidget *parent;
-
- item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
- if (item == NULL)
- /* State is defunct */
- return NULL;
-
- temp_item = item;
- while (TRUE)
- {
- GdkModifierType mnemonic_modifier = 0;
- guint key_val;
- gchar *key, *temp_keybinding;
-
- child = gtk_bin_get_child (GTK_BIN (temp_item));
- if (child == NULL)
- {
- /* Possibly a tear off menu item; it could also be a menu
- * separator generated by gtk_item_factory_create_items()
- */
- return NULL;
- }
- parent = gtk_widget_get_parent (temp_item);
- if (!parent)
- {
- /*
- * parent can be NULL when activating a window from the panel
- */
- return NULL;
- }
- g_return_val_if_fail (GTK_IS_MENU_SHELL (parent), NULL);
- if (GTK_IS_MENU_BAR (parent))
- {
- GtkWidget *toplevel;
-
- toplevel = gtk_widget_get_toplevel (parent);
- if (toplevel && GTK_IS_WINDOW (toplevel))
- mnemonic_modifier = gtk_window_get_mnemonic_modifier (
- GTK_WINDOW (toplevel));
- }
- if (GTK_IS_LABEL (child))
- {
- key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (child));
- if (key_val != GDK_KEY_VoidSymbol)
- {
- key = gtk_accelerator_name (key_val, mnemonic_modifier);
- if (full_keybinding)
- temp_keybinding = g_strconcat (key, ":", full_keybinding, NULL);
- else
- temp_keybinding = g_strconcat (key, NULL);
- if (temp_item == item)
- {
- item_keybinding = g_strdup (key);
- }
- g_free (key);
- g_free (full_keybinding);
- full_keybinding = temp_keybinding;
- }
- else
- {
- /* No keybinding */
- g_free (full_keybinding);
- full_keybinding = NULL;
- break;
- }
- }
- if (GTK_IS_MENU_BAR (parent))
- /* We have reached the menu bar so we are finished */
- break;
- g_return_val_if_fail (GTK_IS_MENU (parent), NULL);
- temp_item = gtk_menu_get_attach_widget (GTK_MENU (parent));
- if (!GTK_IS_MENU_ITEM (temp_item))
- {
- /*
- * Menu is attached to something other than a menu item;
- * probably an option menu
- */
- g_free (full_keybinding);
- full_keybinding = NULL;
- break;
- }
- }
-
- parent = gtk_widget_get_parent (item);
- if (GTK_IS_MENU (parent))
- {
- GtkAccelGroup *group;
- GtkAccelKey *key;
-
- group = gtk_menu_get_accel_group (GTK_MENU (parent));
-
- if (group)
- {
- key = gtk_accel_group_find (group, find_accel, item);
- }
- else
- {
- /*
- * If the menu item is created using GtkAction and GtkUIManager
- * we get here.
- */
- key = NULL;
- child = gtk_bin_get_child (GTK_BIN (item));
- if (GTK_IS_ACCEL_LABEL (child))
- {
- GtkAccelLabel *accel_label;
- GClosure *accel_closure;
-
- accel_label = GTK_ACCEL_LABEL (child);
- g_object_get (accel_label,
- "accel-closure", &accel_closure,
- NULL);
- if (accel_closure)
- {
- key = gtk_accel_group_find (gtk_accel_group_from_accel_closure (accel_closure),
- find_accel_new,
- accel_closure);
- }
-
- }
- }
-
- if (key)
- {
- accelerator = gtk_accelerator_name (key->accel_key,
- key->accel_mods);
- }
- }
- }
- /*
- * Concatenate the bindings
- */
- if (item_keybinding || full_keybinding || accelerator)
- {
- gchar *temp;
- if (item_keybinding)
- {
- keybinding = g_strconcat (item_keybinding, KEYBINDING_SEPARATOR, NULL);
- g_free (item_keybinding);
- }
- else
- keybinding = g_strconcat (KEYBINDING_SEPARATOR, NULL);
-
- if (full_keybinding)
- {
- temp = g_strconcat (keybinding, full_keybinding,
- KEYBINDING_SEPARATOR, NULL);
- g_free (full_keybinding);
- }
- else
- temp = g_strconcat (keybinding, KEYBINDING_SEPARATOR, NULL);
-
- g_free (keybinding);
- keybinding = temp;
- if (accelerator)
- {
- temp = g_strconcat (keybinding, accelerator, NULL);
- g_free (accelerator);
- g_free (keybinding);
- keybinding = temp;
- }
- }
- g_free (gail_menu_item->click_keybinding);
- gail_menu_item->click_keybinding = keybinding;
- return keybinding;
-}
-
-static gboolean
-gail_menu_item_set_description (AtkAction *action,
- gint i,
- const gchar *desc)
-{
- if (i == 0)
- {
- GailMenuItem *item;
-
- item = GAIL_MENU_ITEM (action);
- g_free (item->click_description);
- item->click_description = g_strdup (desc);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static void
-gail_menu_item_finalize (GObject *object)
-{
- GailMenuItem *menu_item = GAIL_MENU_ITEM (object);
-
- g_free (menu_item->click_keybinding);
- g_free (menu_item->click_description);
- if (menu_item->action_idle_handler)
- {
- g_source_remove (menu_item->action_idle_handler);
- menu_item->action_idle_handler = 0;
- }
-
- if (menu_item->textutil)
- {
- g_object_unref (menu_item->textutil);
- }
- if (menu_item->text)
- {
- g_free (menu_item->text);
- menu_item->text = NULL;
- }
-
- G_OBJECT_CLASS (gail_menu_item_parent_class)->finalize (object);
-}
-
-static const gchar *
-gail_menu_item_get_name (AtkObject *obj)
-{
- const gchar* name;
- GtkWidget *widget;
- GtkWidget *label;
-
- name = ATK_OBJECT_CLASS (gail_menu_item_parent_class)->get_name (obj);
-
- if (name)
- return name;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return NULL;
-
- label = get_label_from_container (widget);
- if (GTK_IS_LABEL (label))
- return gtk_label_get_text (GTK_LABEL(label));
-
- return NULL;
-}
-
-static void
-menu_item_select (GtkMenuItem *item)
-{
- menu_item_selection (item, TRUE);
-}
-
-static void
-menu_item_deselect (GtkMenuItem *item)
-{
- menu_item_selection (item, FALSE);
-}
-
-static void
-menu_item_selection (GtkMenuItem *item,
- gboolean selected)
-{
- AtkObject *obj, *parent;
- gint i;
-
- obj = gtk_widget_get_accessible (GTK_WIDGET (item));
- atk_object_notify_state_change (obj, ATK_STATE_SELECTED, selected);
-
- for (i = 0; i < atk_object_get_n_accessible_children (obj); i++)
- {
- AtkObject *child;
- child = atk_object_ref_accessible_child (obj, i);
- atk_object_notify_state_change (child, ATK_STATE_SHOWING, selected);
- g_object_unref (child);
- }
- parent = atk_object_get_parent (obj);
- g_signal_emit_by_name (parent, "selection_changed");
-}
-
-static gboolean
-find_accel (GtkAccelKey *key,
- GClosure *closure,
- gpointer data)
-{
- /*
- * We assume that closure->data points to the widget
- * pending gtk_widget_get_accel_closures being made public
- */
- return data == (gpointer) closure->data;
-}
-
-static gboolean
-find_accel_new (GtkAccelKey *key,
- GClosure *closure,
- gpointer data)
-{
- return data == (gpointer) closure;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_MENU_ITEM_H__
-#define __GAIL_MENU_ITEM_H__
-
-#include "gailcontainer.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_MENU_ITEM (gail_menu_item_get_type ())
-#define GAIL_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_MENU_ITEM, GailMenuItem))
-#define GAIL_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_MENU_ITEM, GailMenuItemClass))
-#define GAIL_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_MENU_ITEM))
-#define GAIL_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_MENU_ITEM))
-#define GAIL_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_MENU_ITEM, GailMenuItemClass))
-
-typedef struct _GailMenuItem GailMenuItem;
-typedef struct _GailMenuItemClass GailMenuItemClass;
-
-struct _GailMenuItem
-{
- GailContainer parent;
-
- GailTextUtil *textutil;
-
- gchar *text;
-
- gchar *click_keybinding;
- gchar *click_description;
- guint action_idle_handler;
-};
-
-GType gail_menu_item_get_type (void);
-
-struct _GailMenuItemClass
-{
- GailContainerClass parent_class;
-};
-
-AtkObject* gail_menu_item_new (GtkWidget *widget);
-
-G_END_DECLS
-
-#endif /* __GAIL_MENU_ITEM_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailmenushell.h"
-
-static void gail_menu_shell_class_init (GailMenuShellClass *klass);
-static void gail_menu_shell_init (GailMenuShell *menu_shell);
-static void gail_menu_shell_initialize (AtkObject *accessible,
- gpointer data);
-static void atk_selection_interface_init (AtkSelectionIface *iface);
-static gboolean gail_menu_shell_add_selection (AtkSelection *selection,
- gint i);
-static gboolean gail_menu_shell_clear_selection (AtkSelection *selection);
-static AtkObject* gail_menu_shell_ref_selection (AtkSelection *selection,
- gint i);
-static gint gail_menu_shell_get_selection_count (AtkSelection *selection);
-static gboolean gail_menu_shell_is_child_selected (AtkSelection *selection,
- gint i);
-static gboolean gail_menu_shell_remove_selection (AtkSelection *selection,
- gint i);
-
-G_DEFINE_TYPE_WITH_CODE (GailMenuShell, gail_menu_shell, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
-
-static void
-gail_menu_shell_class_init (GailMenuShellClass *klass)
-{
- AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
-
- atk_object_class->initialize = gail_menu_shell_initialize;
-}
-
-static void
-gail_menu_shell_init (GailMenuShell *menu_shell)
-{
-}
-
-static void
-gail_menu_shell_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_menu_shell_parent_class)->initialize (accessible, data);
-
- if (GTK_IS_MENU_BAR (data))
- accessible->role = ATK_ROLE_MENU_BAR;
- else
- /*
- * Accessible object for Menu is created in gailmenu.c
- */
- accessible->role = ATK_ROLE_UNKNOWN;
-}
-
-static void
-atk_selection_interface_init (AtkSelectionIface *iface)
-{
- iface->add_selection = gail_menu_shell_add_selection;
- iface->clear_selection = gail_menu_shell_clear_selection;
- iface->ref_selection = gail_menu_shell_ref_selection;
- iface->get_selection_count = gail_menu_shell_get_selection_count;
- iface->is_child_selected = gail_menu_shell_is_child_selected;
- iface->remove_selection = gail_menu_shell_remove_selection;
- /*
- * select_all_selection does not make sense for a menu_shell
- * so no implementation is provided.
- */
-}
-
-static gboolean
-gail_menu_shell_add_selection (AtkSelection *selection,
- gint i)
-{
- GList *kids;
- GtkWidget *item;
- guint length;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- {
- /* State is defunct */
- return FALSE;
- }
-
- kids = gtk_container_get_children (GTK_CONTAINER (widget));
- length = g_list_length (kids);
- if (i < 0 || i > length)
- {
- g_list_free (kids);
- return FALSE;
- }
-
- item = g_list_nth_data (kids, i);
- g_list_free (kids);
- g_return_val_if_fail (GTK_IS_MENU_ITEM(item), FALSE);
- gtk_menu_shell_select_item (GTK_MENU_SHELL (widget), item);
- return TRUE;
-}
-
-static gboolean
-gail_menu_shell_clear_selection (AtkSelection *selection)
-{
- GtkMenuShell *shell;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- {
- /* State is defunct */
- return FALSE;
- }
-
- shell = GTK_MENU_SHELL (widget);
-
- gtk_menu_shell_deselect (shell);
- return TRUE;
-}
-
-static AtkObject*
-gail_menu_shell_ref_selection (AtkSelection *selection,
- gint i)
-{
- GtkMenuShell *shell;
- AtkObject *obj;
- GtkWidget *widget;
- GtkWidget *item;
-
- if (i != 0)
- return NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- {
- /* State is defunct */
- return NULL;
- }
-
- shell = GTK_MENU_SHELL (widget);
-
- item = gtk_menu_shell_get_selected_item (shell);
- if (item != NULL)
- {
- obj = gtk_widget_get_accessible (item);
- g_object_ref (obj);
- return obj;
- }
- else
- {
- return NULL;
- }
-}
-
-static gint
-gail_menu_shell_get_selection_count (AtkSelection *selection)
-{
- GtkMenuShell *shell;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- {
- /* State is defunct */
- return 0;
- }
-
- shell = GTK_MENU_SHELL (widget);
-
- /*
- * Identifies the currently selected menu item
- */
- if (gtk_menu_shell_get_selected_item (shell) == NULL)
- {
- return 0;
- }
- else
- {
- return 1;
- }
-}
-
-static gboolean
-gail_menu_shell_is_child_selected (AtkSelection *selection,
- gint i)
-{
- GtkMenuShell *shell;
- GList *kids;
- gint j;
- GtkWidget *widget;
- GtkWidget *item;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- {
- /* State is defunct */
- return FALSE;
- }
-
- shell = GTK_MENU_SHELL (widget);
- item = gtk_menu_shell_get_selected_item (shell);
- if (item == NULL)
- return FALSE;
-
- kids = gtk_container_get_children (GTK_CONTAINER (shell));
- j = g_list_index (kids, item);
- g_list_free (kids);
-
- return (j==i);
-}
-
-static gboolean
-gail_menu_shell_remove_selection (AtkSelection *selection,
- gint i)
-{
- GtkMenuShell *shell;
- GtkWidget *widget;
- GtkWidget *item;
-
- if (i != 0)
- return FALSE;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- {
- /* State is defunct */
- return FALSE;
- }
-
- shell = GTK_MENU_SHELL (widget);
-
- item = gtk_menu_shell_get_selected_item (shell);
- if (item && gtk_menu_item_get_submenu (GTK_MENU_ITEM (item)))
- {
- /*
- * Menu item contains a menu and it is the selected menu item
- * so deselect it.
- */
- gtk_menu_shell_deselect (shell);
- }
- return TRUE;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_MENU_SHELL_H__
-#define __GAIL_MENU_SHELL_H__
-
-#include "gailcontainer.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_MENU_SHELL (gail_menu_shell_get_type ())
-#define GAIL_MENU_SHELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_MENU_SHELL, GailMenuShell))
-#define GAIL_MENU_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_MENU_SHELL, GailMenuShellClass))
-#define GAIL_IS_MENU_SHELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_MENU_SHELL))
-#define GAIL_IS_MENU_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_MENU_SHELL))
-#define GAIL_MENU_SHELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_MENU_SHELL, GailMenuShellClass))
-
-typedef struct _GailMenuShell GailMenuShell;
-typedef struct _GailMenuShellClass GailMenuShellClass;
-
-struct _GailMenuShell
-{
- GailContainer parent;
-};
-
-GType gail_menu_shell_get_type (void);
-
-struct _GailMenuShellClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_MENU_SHELL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailnotebook.h"
-#include "gailnotebookpage.h"
-#include "gail-private-macros.h"
-
-static void gail_notebook_class_init (GailNotebookClass *klass);
-static void gail_notebook_init (GailNotebook *notebook);
-static void gail_notebook_finalize (GObject *object);
-static void gail_notebook_real_initialize (AtkObject *obj,
- gpointer data);
-
-static void gail_notebook_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-
-static AtkObject* gail_notebook_ref_child (AtkObject *obj,
- gint i);
-static gint gail_notebook_real_remove_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data);
-static void atk_selection_interface_init (AtkSelectionIface *iface);
-static gboolean gail_notebook_add_selection (AtkSelection *selection,
- gint i);
-static AtkObject* gail_notebook_ref_selection (AtkSelection *selection,
- gint i);
-static gint gail_notebook_get_selection_count (AtkSelection *selection);
-static gboolean gail_notebook_is_child_selected (AtkSelection *selection,
- gint i);
-static AtkObject* find_child_in_list (GList *list,
- gint index);
-static void check_cache (GailNotebook *gail_notebook,
- GtkNotebook *notebook);
-static void reset_cache (GailNotebook *gail_notebook,
- gint index);
-static void create_notebook_page_accessible (GailNotebook *gail_notebook,
- GtkNotebook *notebook,
- gint index,
- gboolean insert_before,
- GList *list);
-static void gail_notebook_child_parent_set (GtkWidget *widget,
- GtkWidget *old_parent,
- gpointer data);
-static gboolean gail_notebook_focus_cb (GtkWidget *widget,
- GtkDirectionType type);
-static gboolean gail_notebook_check_focus_tab (gpointer data);
-static void gail_notebook_destroyed (gpointer data);
-
-
-G_DEFINE_TYPE_WITH_CODE (GailNotebook, gail_notebook, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
-
-static void
-gail_notebook_class_init (GailNotebookClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailWidgetClass *widget_class;
- GailContainerClass *container_class;
-
- widget_class = (GailWidgetClass*)klass;
- container_class = (GailContainerClass*)klass;
-
- gobject_class->finalize = gail_notebook_finalize;
-
- widget_class->notify_gtk = gail_notebook_real_notify_gtk;
-
- class->ref_child = gail_notebook_ref_child;
- class->initialize = gail_notebook_real_initialize;
- /*
- * We do not provide an implementation of get_n_children
- * as the implementation in GailContainer returns the correct
- * number of children.
- */
- container_class->remove_gtk = gail_notebook_real_remove_gtk;
-}
-
-static void
-gail_notebook_init (GailNotebook *notebook)
-{
- notebook->page_cache = NULL;
- notebook->selected_page = -1;
- notebook->focus_tab_page = -1;
- notebook->remove_index = -1;
- notebook->idle_focus_id = 0;
-}
-
-static AtkObject*
-gail_notebook_ref_child (AtkObject *obj,
- gint i)
-{
- AtkObject *accessible = NULL;
- GailNotebook *gail_notebook;
- GtkNotebook *gtk_notebook;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- gail_notebook = GAIL_NOTEBOOK (obj);
-
- gtk_notebook = GTK_NOTEBOOK (widget);
-
- if (gail_notebook->page_count < gtk_notebook_get_n_pages (gtk_notebook))
- check_cache (gail_notebook, gtk_notebook);
-
- accessible = find_child_in_list (gail_notebook->page_cache, i);
-
- if (accessible != NULL)
- g_object_ref (accessible);
-
- return accessible;
-}
-
-static void
-gail_notebook_page_added (GtkNotebook *gtk_notebook,
- GtkWidget *child,
- guint page_num,
- gpointer data)
-{
- AtkObject *atk_obj;
- GailNotebook *notebook;
-
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (gtk_notebook));
- notebook = GAIL_NOTEBOOK (atk_obj);
- create_notebook_page_accessible (notebook, gtk_notebook, page_num, FALSE, NULL);
- notebook->page_count++;
-}
-
-static void
-gail_notebook_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GailNotebook *notebook;
- GtkNotebook *gtk_notebook;
- gint i;
-
- ATK_OBJECT_CLASS (gail_notebook_parent_class)->initialize (obj, data);
-
- notebook = GAIL_NOTEBOOK (obj);
- gtk_notebook = GTK_NOTEBOOK (data);
- for (i = 0; i < gtk_notebook_get_n_pages (gtk_notebook); i++)
- {
- create_notebook_page_accessible (notebook, gtk_notebook, i, FALSE, NULL);
- }
- notebook->page_count = i;
- notebook->selected_page = gtk_notebook_get_current_page (gtk_notebook);
-
- g_signal_connect (gtk_notebook,
- "focus",
- G_CALLBACK (gail_notebook_focus_cb),
- NULL);
- g_signal_connect (gtk_notebook,
- "page-added",
- G_CALLBACK (gail_notebook_page_added),
- NULL);
- g_object_weak_ref (G_OBJECT(gtk_notebook),
- (GWeakNotify) gail_notebook_destroyed,
- obj);
-
- obj->role = ATK_ROLE_PAGE_TAB_LIST;
-}
-
-static void
-gail_notebook_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkWidget *widget;
- AtkObject* atk_obj;
-
- widget = GTK_WIDGET (obj);
- atk_obj = gtk_widget_get_accessible (widget);
-
- if (strcmp (pspec->name, "page") == 0)
- {
- gint page_num, old_page_num;
- gint focus_page_num = 0;
- gint old_focus_page_num;
- GailNotebook *gail_notebook;
- GtkNotebook *gtk_notebook;
-
- gail_notebook = GAIL_NOTEBOOK (atk_obj);
- gtk_notebook = GTK_NOTEBOOK (widget);
-
- if (gail_notebook->page_count < gtk_notebook_get_n_pages (gtk_notebook))
- check_cache (gail_notebook, gtk_notebook);
- /*
- * Notify SELECTED state change for old and new page
- */
- old_page_num = gail_notebook->selected_page;
- page_num = gtk_notebook_get_current_page (gtk_notebook);
- gail_notebook->selected_page = page_num;
- gail_notebook->focus_tab_page = page_num;
- old_focus_page_num = gail_notebook->focus_tab_page;
-
- if (page_num != old_page_num)
- {
- AtkObject *obj;
-
- if (old_page_num != -1)
- {
- obj = gail_notebook_ref_child (atk_obj, old_page_num);
- if (obj)
- {
- atk_object_notify_state_change (obj,
- ATK_STATE_SELECTED,
- FALSE);
- g_object_unref (obj);
- }
- }
- obj = gail_notebook_ref_child (atk_obj, page_num);
- if (obj)
- {
- atk_object_notify_state_change (obj,
- ATK_STATE_SELECTED,
- TRUE);
- g_object_unref (obj);
- /*
- * The page which is being displayed has changed but there is
- * no need to tell the focus tracker as the focus page will also
- * change or a widget in the page will receive focus if the
- * Notebook does not have tabs.
- */
- }
- g_signal_emit_by_name (atk_obj, "selection_changed");
- g_signal_emit_by_name (atk_obj, "visible_data_changed");
- }
- if (gtk_notebook_get_show_tabs (gtk_notebook) &&
- (focus_page_num != old_focus_page_num))
- {
- if (gail_notebook->idle_focus_id)
- g_source_remove (gail_notebook->idle_focus_id);
- gail_notebook->idle_focus_id = gdk_threads_add_idle (gail_notebook_check_focus_tab, atk_obj);
- }
- }
- else
- GAIL_WIDGET_CLASS (gail_notebook_parent_class)->notify_gtk (obj, pspec);
-}
-
-static void
-gail_notebook_finalize (GObject *object)
-{
- GailNotebook *notebook = GAIL_NOTEBOOK (object);
- GList *list;
-
- /*
- * Get rid of the GailNotebookPage objects which we have cached.
- */
- list = notebook->page_cache;
- if (list != NULL)
- {
- while (list)
- {
- g_object_unref (list->data);
- list = list->next;
- }
- }
-
- g_list_free (notebook->page_cache);
-
- if (notebook->idle_focus_id)
- g_source_remove (notebook->idle_focus_id);
-
- G_OBJECT_CLASS (gail_notebook_parent_class)->finalize (object);
-}
-
-static void
-atk_selection_interface_init (AtkSelectionIface *iface)
-{
- iface->add_selection = gail_notebook_add_selection;
- iface->ref_selection = gail_notebook_ref_selection;
- iface->get_selection_count = gail_notebook_get_selection_count;
- iface->is_child_selected = gail_notebook_is_child_selected;
- /*
- * The following don't make any sense for GtkNotebook widgets.
- * Unsupported AtkSelection interfaces:
- * clear_selection();
- * remove_selection();
- * select_all_selection();
- */
-}
-
-/*
- * GtkNotebook only supports the selection of one page at a time.
- * Selecting a page unselects any previous selection, so this
- * changes the current selection instead of adding to it.
- */
-static gboolean
-gail_notebook_add_selection (AtkSelection *selection,
- gint i)
-{
- GtkNotebook *notebook;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
- notebook = GTK_NOTEBOOK (widget);
- gtk_notebook_set_current_page (notebook, i);
- return TRUE;
-}
-
-static AtkObject*
-gail_notebook_ref_selection (AtkSelection *selection,
- gint i)
-{
- AtkObject *accessible;
- GtkWidget *widget;
- GtkNotebook *notebook;
- gint pagenum;
-
- /*
- * A note book can have only one selection.
- */
- gail_return_val_if_fail (i == 0, NULL);
- g_return_val_if_fail (GAIL_IS_NOTEBOOK (selection), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- notebook = GTK_NOTEBOOK (widget);
- pagenum = gtk_notebook_get_current_page (notebook);
- gail_return_val_if_fail (pagenum != -1, NULL);
- accessible = gail_notebook_ref_child (ATK_OBJECT (selection), pagenum);
-
- return accessible;
-}
-
-/*
- * Always return 1 because there can only be one page
- * selected at any time
- */
-static gint
-gail_notebook_get_selection_count (AtkSelection *selection)
-{
- GtkWidget *widget;
- GtkNotebook *notebook;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return 0;
-
- notebook = GTK_NOTEBOOK (widget);
- if (notebook == NULL || gtk_notebook_get_current_page (notebook) == -1)
- return 0;
- else
- return 1;
-}
-
-static gboolean
-gail_notebook_is_child_selected (AtkSelection *selection,
- gint i)
-{
- GtkWidget *widget;
- GtkNotebook *notebook;
- gint pagenumber;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
-
-
- notebook = GTK_NOTEBOOK (widget);
- pagenumber = gtk_notebook_get_current_page(notebook);
-
- if (pagenumber == i)
- return TRUE;
- else
- return FALSE;
-}
-
-static AtkObject*
-find_child_in_list (GList *list,
- gint index)
-{
- AtkObject *obj = NULL;
-
- while (list)
- {
- if (GAIL_NOTEBOOK_PAGE (list->data)->index == index)
- {
- obj = ATK_OBJECT (list->data);
- break;
- }
- list = list->next;
- }
- return obj;
-}
-
-static void
-check_cache (GailNotebook *gail_notebook,
- GtkNotebook *notebook)
-{
- GList *gtk_list;
- GList *gail_list;
- gint i;
-
- gtk_list = gtk_container_get_children (GTK_CONTAINER (notebook));
- gail_list = gail_notebook->page_cache;
-
- i = 0;
- while (gtk_list)
- {
- if (!gail_list)
- {
- create_notebook_page_accessible (gail_notebook, notebook, i, FALSE, NULL);
- }
- else if (GAIL_NOTEBOOK_PAGE (gail_list->data)->page != gtk_list->data)
- {
- create_notebook_page_accessible (gail_notebook, notebook, i, TRUE, gail_list);
- }
- else
- {
- gail_list = gail_list->next;
- }
- i++;
- gtk_list = gtk_list->next;
- }
- g_list_free (gtk_list);
-
- gail_notebook->page_count = i;
-}
-
-static void
-reset_cache (GailNotebook *gail_notebook,
- gint index)
-{
- GList *l;
-
- for (l = gail_notebook->page_cache; l; l = l->next)
- {
- if (GAIL_NOTEBOOK_PAGE (l->data)->index > index)
- GAIL_NOTEBOOK_PAGE (l->data)->index -= 1;
- }
-}
-
-static void
-create_notebook_page_accessible (GailNotebook *gail_notebook,
- GtkNotebook *notebook,
- gint index,
- gboolean insert_before,
- GList *list)
-{
- AtkObject *obj;
-
- obj = gail_notebook_page_new (notebook, index);
- g_object_ref (obj);
- if (insert_before)
- gail_notebook->page_cache = g_list_insert_before (gail_notebook->page_cache, list, obj);
- else
- gail_notebook->page_cache = g_list_append (gail_notebook->page_cache, obj);
- g_signal_connect (gtk_notebook_get_nth_page (notebook, index),
- "parent_set",
- G_CALLBACK (gail_notebook_child_parent_set),
- obj);
-}
-
-static void
-gail_notebook_child_parent_set (GtkWidget *widget,
- GtkWidget *old_parent,
- gpointer data)
-{
- GailNotebook *gail_notebook;
-
- gail_return_if_fail (old_parent != NULL);
- gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (old_parent));
- gail_notebook->remove_index = GAIL_NOTEBOOK_PAGE (data)->index;
-}
-
-static gint
-gail_notebook_real_remove_gtk (GtkContainer *container,
- GtkWidget *widget,
- gpointer data)
-{
- GailNotebook *gail_notebook;
- AtkObject *obj;
- gint index;
-
- g_return_val_if_fail (container != NULL, 1);
- gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (GTK_WIDGET (container)));
- index = gail_notebook->remove_index;
- gail_notebook->remove_index = -1;
-
- obj = find_child_in_list (gail_notebook->page_cache, index);
- g_return_val_if_fail (obj, 1);
- gail_notebook->page_cache = g_list_remove (gail_notebook->page_cache, obj);
- gail_notebook->page_count -= 1;
- reset_cache (gail_notebook, index);
- g_signal_emit_by_name (gail_notebook,
- "children_changed::remove",
- GAIL_NOTEBOOK_PAGE (obj)->index,
- obj, NULL);
- g_object_unref (obj);
- return 1;
-}
-
-static gboolean
-gail_notebook_focus_cb (GtkWidget *widget,
- GtkDirectionType type)
-{
- AtkObject *atk_obj = gtk_widget_get_accessible (widget);
- GailNotebook *gail_notebook = GAIL_NOTEBOOK (atk_obj);
-
- switch (type)
- {
- case GTK_DIR_LEFT:
- case GTK_DIR_RIGHT:
- if (gail_notebook->idle_focus_id == 0)
- gail_notebook->idle_focus_id = gdk_threads_add_idle (gail_notebook_check_focus_tab, atk_obj);
- break;
- default:
- break;
- }
- return FALSE;
-}
-
-static gboolean
-gail_notebook_check_focus_tab (gpointer data)
-{
- GtkWidget *widget;
- AtkObject *atk_obj;
- gint focus_page_num, old_focus_page_num;
- GailNotebook *gail_notebook;
- GtkNotebook *gtk_notebook;
-
- atk_obj = ATK_OBJECT (data);
- gail_notebook = GAIL_NOTEBOOK (atk_obj);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj));
-
- gtk_notebook = GTK_NOTEBOOK (widget);
-
- gail_notebook->idle_focus_id = 0;
-
- focus_page_num = gtk_notebook_get_current_page (gtk_notebook);
- if (focus_page_num == -1)
- return FALSE;
-
- old_focus_page_num = gail_notebook->focus_tab_page;
- gail_notebook->focus_tab_page = focus_page_num;
- if (old_focus_page_num != focus_page_num)
- {
- AtkObject *obj;
-
- obj = atk_object_ref_accessible_child (atk_obj, focus_page_num);
- atk_focus_tracker_notify (obj);
- g_object_unref (obj);
- }
-
- return FALSE;
-}
-
-static void
-gail_notebook_destroyed (gpointer data)
-{
- GailNotebook *gail_notebook = GAIL_NOTEBOOK (data);
-
- if (gail_notebook->idle_focus_id)
- {
- g_source_remove (gail_notebook->idle_focus_id);
- gail_notebook->idle_focus_id = 0;
- }
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_NOTEBOOK_H__
-#define __GAIL_NOTEBOOK_H__
-
-#include "gailcontainer.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_NOTEBOOK (gail_notebook_get_type ())
-#define GAIL_NOTEBOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_NOTEBOOK, GailNotebook))
-#define GAIL_NOTEBOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_NOTEBOOK, GailNotebookClass))
-#define GAIL_IS_NOTEBOOK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_NOTEBOOK))
-#define GAIL_IS_NOTEBOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_NOTEBOOK))
-#define GAIL_NOTEBOOK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_NOTEBOOK, GailNotebookClass))
-
-typedef struct _GailNotebook GailNotebook;
-typedef struct _GailNotebookClass GailNotebookClass;
-
-struct _GailNotebook
-{
- GailContainer parent;
-
- /*
- * page_cache maintains a list of pre-ref'd Notebook Pages.
- * This cache is queried by gail_notebook_ref_child().
- * If the page is found in the list then a new page does not
- * need to be created
- */
- GList* page_cache;
- gint selected_page;
- gint focus_tab_page;
- gint page_count;
- guint idle_focus_id;
-
- gint remove_index;
-};
-
-GType gail_notebook_get_type (void);
-
-struct _GailNotebookClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_NOTEBOOK_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailnotebookpage.h"
-#include <libgail-util/gailmisc.h>
-#include "gail-private-macros.h"
-
-static void gail_notebook_page_class_init (GailNotebookPageClass *klass);
-static void gail_notebook_page_init (GailNotebookPage *page);
-static void gail_notebook_page_finalize (GObject *object);
-static void gail_notebook_page_label_map_gtk (GtkWidget *widget,
- gpointer data);
-
-static const gchar* gail_notebook_page_get_name (AtkObject *accessible);
-static AtkObject* gail_notebook_page_get_parent (AtkObject *accessible);
-static gint gail_notebook_page_get_n_children (AtkObject *accessible);
-static AtkObject* gail_notebook_page_ref_child (AtkObject *accessible,
- gint i);
-static gint gail_notebook_page_get_index_in_parent
- (AtkObject *accessible);
-static AtkStateSet* gail_notebook_page_ref_state_set (AtkObject *accessible);
-
-static gint gail_notebook_page_notify (GObject *obj,
- GParamSpec *pspec,
- gpointer user_data);
-static void gail_notebook_page_init_textutil (GailNotebookPage *notebook_page,
- GtkWidget *label);
-
-static void atk_component_interface_init (AtkComponentIface *iface);
-
-static AtkObject* gail_notebook_page_ref_accessible_at_point
- (AtkComponent *component,
- gint x,
- gint y,
- AtkCoordType coord_type);
-
-static void gail_notebook_page_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type);
-
-static AtkObject* _gail_notebook_page_get_tab_label (GailNotebookPage *page);
-
-/* atktext.h */
-static void atk_text_interface_init (AtkTextIface *iface);
-
-static gchar* gail_notebook_page_get_text (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gunichar gail_notebook_page_get_character_at_offset
- (AtkText *text,
- gint offset);
-static gchar* gail_notebook_page_get_text_before_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_notebook_page_get_text_at_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_notebook_page_get_text_after_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gint gail_notebook_page_get_character_count (AtkText *text);
-static void gail_notebook_page_get_character_extents
- (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static gint gail_notebook_page_get_offset_at_point
- (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static AtkAttributeSet* gail_notebook_page_get_run_attributes
- (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet* gail_notebook_page_get_default_attributes
- (AtkText *text);
-static GtkWidget* get_label_from_notebook_page (GailNotebookPage *page);
-static GtkWidget* find_label_child (GtkContainer *container);
-
-/* FIXME: not GAIL_TYPE_OBJECT? */
-G_DEFINE_TYPE_WITH_CODE (GailNotebookPage, gail_notebook_page, ATK_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
-
-static void
-gail_notebook_page_class_init (GailNotebookPageClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->get_name = gail_notebook_page_get_name;
- class->get_parent = gail_notebook_page_get_parent;
- class->get_n_children = gail_notebook_page_get_n_children;
- class->ref_child = gail_notebook_page_ref_child;
- class->ref_state_set = gail_notebook_page_ref_state_set;
- class->get_index_in_parent = gail_notebook_page_get_index_in_parent;
-
- gobject_class->finalize = gail_notebook_page_finalize;
-}
-
-static void
-gail_notebook_page_init (GailNotebookPage *page)
-{
-}
-
-static gint
-notify_child_added (gpointer data)
-{
- GailNotebookPage *page;
- AtkObject *atk_object, *atk_parent;
-
- g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (data), FALSE);
- page = GAIL_NOTEBOOK_PAGE (data);
- atk_object = ATK_OBJECT (data);
-
- page->notify_child_added_id = 0;
-
- /* The widget page->notebook may be deleted before this handler is called */
- if (page->notebook != NULL)
- {
- atk_parent = gtk_widget_get_accessible (GTK_WIDGET (page->notebook));
- atk_object_set_parent (atk_object, atk_parent);
- g_signal_emit_by_name (atk_parent, "children_changed::add", page->index, atk_object, NULL);
- }
-
- return FALSE;
-}
-
-AtkObject*
-gail_notebook_page_new (GtkNotebook *notebook,
- gint pagenum)
-{
- GObject *object;
- AtkObject *atk_object;
- GailNotebookPage *page;
- GtkWidget *child;
- GtkWidget *label;
- GtkWidget *widget_page;
-
- g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
-
- child = gtk_notebook_get_nth_page (notebook, pagenum);
-
- if (!child)
- return NULL;
-
- object = g_object_new (GAIL_TYPE_NOTEBOOK_PAGE, NULL);
- g_return_val_if_fail (object != NULL, NULL);
-
- page = GAIL_NOTEBOOK_PAGE (object);
- page->notebook = notebook;
- g_object_add_weak_pointer (G_OBJECT (page->notebook), (gpointer *)&page->notebook);
- page->index = pagenum;
- widget_page = gtk_notebook_get_nth_page (notebook, pagenum);
- page->page = widget_page;
- page->textutil = NULL;
-
- atk_object = ATK_OBJECT (page);
- atk_object->role = ATK_ROLE_PAGE_TAB;
- atk_object->layer = ATK_LAYER_WIDGET;
-
- page->notify_child_added_id = gdk_threads_add_idle (notify_child_added, atk_object);
- /*
- * We get notified of changes to the label
- */
- label = get_label_from_notebook_page (page);
- if (GTK_IS_LABEL (label))
- {
- if (gtk_widget_get_mapped (label))
- gail_notebook_page_init_textutil (page, label);
- else
- g_signal_connect (label,
- "map",
- G_CALLBACK (gail_notebook_page_label_map_gtk),
- page);
- }
-
- return atk_object;
-}
-
-static void
-gail_notebook_page_label_map_gtk (GtkWidget *widget,
- gpointer data)
-{
- GailNotebookPage *page;
-
- page = GAIL_NOTEBOOK_PAGE (data);
- gail_notebook_page_init_textutil (page, widget);
-}
-
-static void
-gail_notebook_page_init_textutil (GailNotebookPage *page,
- GtkWidget *label)
-{
- const gchar *label_text;
-
- if (page->textutil == NULL)
- {
- page->textutil = gail_text_util_new ();
- g_signal_connect (label,
- "notify",
- (GCallback) gail_notebook_page_notify,
- page);
- }
- label_text = gtk_label_get_text (GTK_LABEL (label));
- gail_text_util_text_setup (page->textutil, label_text);
-}
-
-static gint
-gail_notebook_page_notify (GObject *obj,
- GParamSpec *pspec,
- gpointer user_data)
-{
- AtkObject *atk_obj = ATK_OBJECT (user_data);
- GtkLabel *label;
- GailNotebookPage *page;
-
- if (strcmp (pspec->name, "label") == 0)
- {
- const gchar* label_text;
-
- label = GTK_LABEL (obj);
-
- label_text = gtk_label_get_text (label);
-
- page = GAIL_NOTEBOOK_PAGE (atk_obj);
- gail_text_util_text_setup (page->textutil, label_text);
-
- if (atk_obj->name == NULL)
- {
- /*
- * The label has changed so notify a change in accessible-name
- */
- g_object_notify (G_OBJECT (atk_obj), "accessible-name");
- }
- /*
- * The label is the only property which can be changed
- */
- g_signal_emit_by_name (atk_obj, "visible_data_changed");
- }
- return 1;
-}
-
-static void
-gail_notebook_page_finalize (GObject *object)
-{
- GailNotebookPage *page = GAIL_NOTEBOOK_PAGE (object);
-
- if (page->notebook)
- g_object_remove_weak_pointer (G_OBJECT (page->notebook), (gpointer *)&page->notebook);
-
- if (page->textutil)
- g_object_unref (page->textutil);
-
- if (page->notify_child_added_id)
- g_source_remove (page->notify_child_added_id);
-
- G_OBJECT_CLASS (gail_notebook_page_parent_class)->finalize (object);
-}
-
-static const gchar*
-gail_notebook_page_get_name (AtkObject *accessible)
-{
- g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), NULL);
-
- if (accessible->name != NULL)
- return accessible->name;
- else
- {
- GtkWidget *label;
-
- label = get_label_from_notebook_page (GAIL_NOTEBOOK_PAGE (accessible));
- if (GTK_IS_LABEL (label))
- return gtk_label_get_text (GTK_LABEL (label));
- else
- return NULL;
- }
-}
-
-static AtkObject*
-gail_notebook_page_get_parent (AtkObject *accessible)
-{
- GailNotebookPage *page;
-
- g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), NULL);
-
- page = GAIL_NOTEBOOK_PAGE (accessible);
-
- if (!page->notebook)
- return NULL;
-
- return gtk_widget_get_accessible (GTK_WIDGET (page->notebook));
-}
-
-static gint
-gail_notebook_page_get_n_children (AtkObject *accessible)
-{
- /* Notebook page has only one child */
- g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), 0);
-
- return 1;
-}
-
-static AtkObject*
-gail_notebook_page_ref_child (AtkObject *accessible,
- gint i)
-{
- GtkWidget *child;
- AtkObject *child_obj;
- GailNotebookPage *page = NULL;
-
- g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), NULL);
- if (i != 0)
- return NULL;
-
- page = GAIL_NOTEBOOK_PAGE (accessible);
- if (!page->notebook)
- return NULL;
-
- child = gtk_notebook_get_nth_page (page->notebook, page->index);
- gail_return_val_if_fail (GTK_IS_WIDGET (child), NULL);
-
- child_obj = gtk_widget_get_accessible (child);
- g_object_ref (child_obj);
- return child_obj;
-}
-
-static gint
-gail_notebook_page_get_index_in_parent (AtkObject *accessible)
-{
- GailNotebookPage *page;
-
- g_return_val_if_fail (GAIL_IS_NOTEBOOK_PAGE (accessible), -1);
- page = GAIL_NOTEBOOK_PAGE (accessible);
-
- return page->index;
-}
-
-static AtkStateSet*
-gail_notebook_page_ref_state_set (AtkObject *accessible)
-{
- AtkStateSet *state_set, *label_state_set, *merged_state_set;
- AtkObject *atk_label;
-
- g_return_val_if_fail (GAIL_NOTEBOOK_PAGE (accessible), NULL);
-
- state_set = ATK_OBJECT_CLASS (gail_notebook_page_parent_class)->ref_state_set (accessible);
-
- atk_label = _gail_notebook_page_get_tab_label (GAIL_NOTEBOOK_PAGE (accessible));
- if (atk_label)
- {
- label_state_set = atk_object_ref_state_set (atk_label);
- merged_state_set = atk_state_set_or_sets (state_set, label_state_set);
- g_object_unref (label_state_set);
- g_object_unref (state_set);
- }
- else
- {
- AtkObject *child;
-
- child = atk_object_ref_accessible_child (accessible, 0);
- gail_return_val_if_fail (child, state_set);
-
- merged_state_set = state_set;
- state_set = atk_object_ref_state_set (child);
- if (atk_state_set_contains_state (state_set, ATK_STATE_VISIBLE))
- {
- atk_state_set_add_state (merged_state_set, ATK_STATE_VISIBLE);
- if (atk_state_set_contains_state (state_set, ATK_STATE_ENABLED))
- atk_state_set_add_state (merged_state_set, ATK_STATE_ENABLED);
- if (atk_state_set_contains_state (state_set, ATK_STATE_SHOWING))
- atk_state_set_add_state (merged_state_set, ATK_STATE_SHOWING);
-
- }
- g_object_unref (state_set);
- g_object_unref (child);
- }
- return merged_state_set;
-}
-
-
-static void
-atk_component_interface_init (AtkComponentIface *iface)
-{
- /*
- * We use the default implementations for contains, get_position, get_size
- */
- iface->ref_accessible_at_point = gail_notebook_page_ref_accessible_at_point;
- iface->get_extents = gail_notebook_page_get_extents;
-}
-
-static AtkObject*
-gail_notebook_page_ref_accessible_at_point (AtkComponent *component,
- gint x,
- gint y,
- AtkCoordType coord_type)
-{
- /*
- * There is only one child so we return it.
- */
- AtkObject* child;
-
- g_return_val_if_fail (ATK_IS_OBJECT (component), NULL);
-
- child = atk_object_ref_accessible_child (ATK_OBJECT (component), 0);
- return child;
-}
-
-static void
-gail_notebook_page_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type)
-{
- AtkObject *atk_label;
-
- g_return_if_fail (GAIL_IS_NOTEBOOK_PAGE (component));
-
- atk_label = _gail_notebook_page_get_tab_label (GAIL_NOTEBOOK_PAGE (component));
-
- if (!atk_label)
- {
- AtkObject *child;
-
- *width = 0;
- *height = 0;
-
- child = atk_object_ref_accessible_child (ATK_OBJECT (component), 0);
- gail_return_if_fail (child);
-
- atk_component_get_position (ATK_COMPONENT (child), x, y, coord_type);
- g_object_unref (child);
- }
- else
- {
- atk_component_get_extents (ATK_COMPONENT (atk_label),
- x, y, width, height, coord_type);
- }
- return;
-}
-
-static AtkObject*
-_gail_notebook_page_get_tab_label (GailNotebookPage *page)
-{
- GtkWidget *label;
-
- label = get_label_from_notebook_page (page);
- if (label)
- return gtk_widget_get_accessible (label);
- else
- return NULL;
-}
-
-/* atktext.h */
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_notebook_page_get_text;
- iface->get_character_at_offset = gail_notebook_page_get_character_at_offset;
- iface->get_text_before_offset = gail_notebook_page_get_text_before_offset;
- iface->get_text_at_offset = gail_notebook_page_get_text_at_offset;
- iface->get_text_after_offset = gail_notebook_page_get_text_after_offset;
- iface->get_character_count = gail_notebook_page_get_character_count;
- iface->get_character_extents = gail_notebook_page_get_character_extents;
- iface->get_offset_at_point = gail_notebook_page_get_offset_at_point;
- iface->get_run_attributes = gail_notebook_page_get_run_attributes;
- iface->get_default_attributes = gail_notebook_page_get_default_attributes;
-}
-
-static gchar*
-gail_notebook_page_get_text (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
- const gchar *label_text;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL (label))
- return NULL;
-
- if (!notebook_page->textutil)
- gail_notebook_page_init_textutil (notebook_page, label);
-
- label_text = gtk_label_get_text (GTK_LABEL (label));
-
- if (label_text == NULL)
- return NULL;
- else
- {
- return gail_text_util_get_substring (notebook_page->textutil,
- start_pos, end_pos);
- }
-}
-
-static gchar*
-gail_notebook_page_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- if (!notebook_page->textutil)
- gail_notebook_page_init_textutil (notebook_page, label);
-
- return gail_text_util_get_text (notebook_page->textutil,
- gtk_label_get_layout (GTK_LABEL (label)), GAIL_BEFORE_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_notebook_page_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- if (!notebook_page->textutil)
- gail_notebook_page_init_textutil (notebook_page, label);
-
- return gail_text_util_get_text (notebook_page->textutil,
- gtk_label_get_layout (GTK_LABEL (label)), GAIL_AT_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_notebook_page_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- if (!notebook_page->textutil)
- gail_notebook_page_init_textutil (notebook_page, label);
-
- return gail_text_util_get_text (notebook_page->textutil,
- gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gint
-gail_notebook_page_get_character_count (AtkText *text)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL(label))
- return 0;
-
- return g_utf8_strlen (gtk_label_get_text (GTK_LABEL (label)), -1);
-}
-
-static void
-gail_notebook_page_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
- PangoRectangle char_rect;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL(label))
- return;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
- pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
-
- gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
- x_layout, y_layout, x, y, width, height, coords);
-}
-
-static gint
-gail_notebook_page_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL(label))
- return -1;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
-
- index = gail_misc_get_index_at_point_in_layout (label,
- gtk_label_get_layout (GTK_LABEL (label)),
- x_layout, y_layout, x, y, coords);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- if (index == -1)
- {
- if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
- return g_utf8_strlen (label_text, -1);
-
- return index;
- }
- else
- return g_utf8_pointer_to_offset (label_text, label_text + index);
-}
-
-static AtkAttributeSet*
-gail_notebook_page_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
- AtkAttributeSet *at_set = NULL;
- GtkJustification justify;
- GtkTextDirection dir;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- /* Get values set for entire label, if any */
- justify = gtk_label_get_justify (GTK_LABEL (label));
- if (justify != GTK_JUSTIFY_CENTER)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_JUSTIFICATION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
- }
- dir = gtk_widget_get_direction (label);
- if (dir == GTK_TEXT_DIR_RTL)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_DIRECTION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
- }
-
- at_set = gail_misc_layout_get_run_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- (gchar *) gtk_label_get_text (GTK_LABEL (label)),
- offset,
- start_offset,
- end_offset);
- return at_set;
-}
-
-static AtkAttributeSet*
-gail_notebook_page_get_default_attributes (AtkText *text)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
- AtkAttributeSet *at_set = NULL;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- at_set = gail_misc_get_default_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- label);
- return at_set;
-}
-
-static gunichar
-gail_notebook_page_get_character_at_offset (AtkText *text,
- gint offset)
-{
- GtkWidget *label;
- GailNotebookPage *notebook_page;
- const gchar *string;
- gchar *index;
-
- notebook_page = GAIL_NOTEBOOK_PAGE (text);
- label = get_label_from_notebook_page (notebook_page);
-
- if (!GTK_IS_LABEL(label))
- return '\0';
- string = gtk_label_get_text (GTK_LABEL (label));
- if (offset >= g_utf8_strlen (string, -1))
- return '\0';
- index = g_utf8_offset_to_pointer (string, offset);
-
- return g_utf8_get_char (index);
-}
-
-static GtkWidget*
-get_label_from_notebook_page (GailNotebookPage *page)
-{
- GtkWidget *child;
- GtkNotebook *notebook;
-
- notebook = page->notebook;
- if (!notebook)
- return NULL;
-
- if (!gtk_notebook_get_show_tabs (notebook))
- return NULL;
-
- child = gtk_notebook_get_nth_page (notebook, page->index);
- if (child == NULL) return NULL;
- g_return_val_if_fail (GTK_IS_WIDGET (child), NULL);
-
- child = gtk_notebook_get_tab_label (notebook, child);
-
- if (GTK_IS_LABEL (child))
- return child;
-
- if (GTK_IS_CONTAINER (child))
- child = find_label_child (GTK_CONTAINER (child));
-
- return child;
-}
-
-static GtkWidget*
-find_label_child (GtkContainer *container)
-{
- GList *children, *tmp_list;
- GtkWidget *child;
-
- children = gtk_container_get_children (container);
-
- child = NULL;
- for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
- {
- if (GTK_IS_LABEL (tmp_list->data))
- {
- child = GTK_WIDGET (tmp_list->data);
- break;
- }
- else if (GTK_IS_CONTAINER (tmp_list->data))
- {
- child = find_label_child (GTK_CONTAINER (tmp_list->data));
- if (child)
- break;
- }
- }
- g_list_free (children);
- return child;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_NOTEBOOK_PAGE_H__
-#define __GAIL_NOTEBOOK_PAGE_H__
-
-#include "gailnotebook.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_NOTEBOOK_PAGE (gail_notebook_page_get_type ())
-#define GAIL_NOTEBOOK_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),GAIL_TYPE_NOTEBOOK_PAGE, GailNotebookPage))
-#define GAIL_NOTEBOOK_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_NOTEBOOK_PAGE, GailNotebookPageClass))
-#define GAIL_IS_NOTEBOOK_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_NOTEBOOK_PAGE))
-#define GAIL_IS_NOTEBOOK_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_NOTEBOOK_PAGE))
-#define GAIL_NOTEBOOK_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_NOTEBOOK_PAGE, GailNotebookPageClass))
-
-typedef struct _GailNotebookPage GailNotebookPage;
-typedef struct _GailNotebookPageClass GailNotebookPageClass;
-
-struct _GailNotebookPage
-{
- AtkObject parent;
-
- GtkNotebook *notebook;
-#ifndef GTK_DISABLE_DEPRECATED
- GtkNotebookPage *page;
-#else
- gpointer page;
-#endif
-
- gint index;
- guint notify_child_added_id;
-
- GailTextUtil *textutil;
-};
-
-GType gail_notebook_page_get_type (void);
-
-struct _GailNotebookPageClass
-{
- AtkObjectClass parent_class;
-};
-
-AtkObject *gail_notebook_page_new(GtkNotebook *notebook, gint pagenum);
-
-G_END_DECLS
-
-#endif /* __GAIL_NOTEBOOK_PAGE_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailpaned.h"
-
-static void gail_paned_class_init (GailPanedClass *klass);
-
-static void gail_paned_init (GailPaned *paned);
-
-static void gail_paned_real_initialize (AtkObject *obj,
- gpointer data);
-static void gail_paned_size_allocate_gtk (GtkWidget *widget,
- GtkAllocation *allocation);
-static void atk_value_interface_init (AtkValueIface *iface);
-static void gail_paned_get_current_value (AtkValue *obj,
- GValue *value);
-static void gail_paned_get_maximum_value (AtkValue *obj,
- GValue *value);
-static void gail_paned_get_minimum_value (AtkValue *obj,
- GValue *value);
-static gboolean gail_paned_set_current_value (AtkValue *obj,
- const GValue *value);
-
-G_DEFINE_TYPE_WITH_CODE (GailPaned, gail_paned, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
-
-static void
-gail_paned_class_init (GailPanedClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->initialize = gail_paned_real_initialize;
-}
-
-static void
-gail_paned_init (GailPaned *paned)
-{
-}
-
-static void
-gail_paned_real_initialize (AtkObject *obj,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_paned_parent_class)->initialize (obj, data);
-
- g_signal_connect (data,
- "size_allocate",
- G_CALLBACK (gail_paned_size_allocate_gtk),
- NULL);
-
- obj->role = ATK_ROLE_SPLIT_PANE;
-}
-
-static void
-gail_paned_size_allocate_gtk (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- AtkObject *obj = gtk_widget_get_accessible (widget);
-
- g_object_notify (G_OBJECT (obj), "accessible-value");
-}
-
-
-static void
-atk_value_interface_init (AtkValueIface *iface)
-{
- iface->get_current_value = gail_paned_get_current_value;
- iface->get_maximum_value = gail_paned_get_maximum_value;
- iface->get_minimum_value = gail_paned_get_minimum_value;
- iface->set_current_value = gail_paned_set_current_value;
-}
-
-static void
-gail_paned_get_current_value (AtkValue *obj,
- GValue *value)
-{
- GtkWidget* widget;
- gint current_value;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- current_value = gtk_paned_get_position (GTK_PANED (widget));
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_INT);
- g_value_set_int (value,current_value);
-}
-
-static void
-gail_paned_get_maximum_value (AtkValue *obj,
- GValue *value)
-{
- GtkWidget* widget;
- gint maximum_value;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- g_object_get (GTK_PANED (widget),
- "max-position", &maximum_value,
- NULL);
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_INT);
- g_value_set_int (value, maximum_value);
-}
-
-static void
-gail_paned_get_minimum_value (AtkValue *obj,
- GValue *value)
-{
- GtkWidget* widget;
- gint minimum_value;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- g_object_get (GTK_PANED (widget),
- "min-position", &minimum_value,
- NULL);
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_INT);
- g_value_set_int (value, minimum_value);
-}
-
-/*
- * Calling atk_value_set_current_value() is no guarantee that the value is
- * acceptable; it is necessary to listen for accessible-value signals
- * and check whether the current value has been changed or check what the
- * maximum and minimum values are.
- */
-
-static gboolean
-gail_paned_set_current_value (AtkValue *obj,
- const GValue *value)
-{
- GtkWidget* widget;
- gint new_value;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- if (G_VALUE_HOLDS_INT (value))
- {
- new_value = g_value_get_int (value);
- gtk_paned_set_position (GTK_PANED (widget), new_value);
-
- return TRUE;
- }
- else
- return FALSE;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_PANED_H__
-#define __GAIL_PANED_H__
-
-#include "gailcontainer.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_PANED (gail_paned_get_type ())
-#define GAIL_PANED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_PANED, GailPaned))
-#define GAIL_PANED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_PANED, GailPanedClass))
-#define GAIL_IS_PANED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_PANED))
-#define GAIL_IS_PANED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_PANED))
-#define GAIL_PANED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_PANED, GailPanedClass))
-
-typedef struct _GailPaned GailPaned;
-typedef struct _GailPanedClass GailPanedClass;
-
-struct _GailPaned
-{
- GailContainer parent;
-};
-
-GType gail_paned_get_type (void);
-
-struct _GailPanedClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_PANED_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-#include "gailprogressbar.h"
-#include "gailadjustment.h"
-
-static void gail_progress_bar_class_init (GailProgressBarClass *klass);
-static void gail_progress_bar_init (GailProgressBar *bar);
-static void gail_progress_bar_real_initialize (AtkObject *obj,
- gpointer data);
-
-static void atk_value_interface_init (AtkValueIface *iface);
-
-
-static void gail_progress_bar_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-
-static void gail_progress_bar_get_current_value (AtkValue *obj,
- GValue *value);
-static void gail_progress_bar_get_maximum_value (AtkValue *obj,
- GValue *value);
-static void gail_progress_bar_get_minimum_value (AtkValue *obj,
- GValue *value);
-
-G_DEFINE_TYPE_WITH_CODE (GailProgressBar, gail_progress_bar, GAIL_TYPE_WIDGET,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
-
-static void
-gail_progress_bar_class_init (GailProgressBarClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailWidgetClass *widget_class;
-
- widget_class = (GailWidgetClass*)klass;
-
- widget_class->notify_gtk = gail_progress_bar_real_notify_gtk;
-
- class->initialize = gail_progress_bar_real_initialize;
-}
-
-static void
-gail_progress_bar_init (GailProgressBar *bar)
-{
-}
-
-static void
-gail_progress_bar_real_initialize (AtkObject *obj,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_progress_bar_parent_class)->initialize (obj, data);
-
- obj->role = ATK_ROLE_PROGRESS_BAR;
-}
-
-static void
-atk_value_interface_init (AtkValueIface *iface)
-{
- iface->get_current_value = gail_progress_bar_get_current_value;
- iface->get_maximum_value = gail_progress_bar_get_maximum_value;
- iface->get_minimum_value = gail_progress_bar_get_minimum_value;
-}
-
-static void
-gail_progress_bar_get_current_value (AtkValue *obj,
- GValue *value)
-{
- GtkWidget *widget;
-
- g_return_if_fail (GAIL_IS_PROGRESS_BAR (obj));
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
-
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_DOUBLE);
- g_value_set_double (value, gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (widget)));
-}
-
-static void
-gail_progress_bar_get_maximum_value (AtkValue *obj,
- GValue *value)
-{
- g_return_if_fail (GAIL_IS_PROGRESS_BAR (obj));
-
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_DOUBLE);
- g_value_set_double (value, 1.0);
-}
-
-static void
-gail_progress_bar_get_minimum_value (AtkValue *obj,
- GValue *value)
-{
- g_return_if_fail (GAIL_IS_PROGRESS_BAR (obj));
-
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_DOUBLE);
- g_value_set_double (value, 0.0);
-}
-
-static void
-gail_progress_bar_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkWidget *widget = GTK_WIDGET (obj);
- GailProgressBar *progress_bar = GAIL_PROGRESS_BAR (gtk_widget_get_accessible (widget));
-
- if (strcmp (pspec->name, "fraction") == 0)
- g_object_notify (G_OBJECT (progress_bar), "accessible-value");
- else
- GAIL_WIDGET_CLASS (gail_progress_bar_parent_class)->notify_gtk (obj, pspec);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_PROGRESS_BAR_H__
-#define __GAIL_PROGRESS_BAR_H__
-
-#include "gailwidget.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_PROGRESS_BAR (gail_progress_bar_get_type ())
-#define GAIL_PROGRESS_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_PROGRESS_BAR, GailProgressBar))
-#define GAIL_PROGRESS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_PROGRESS_BAR, GailProgressBarClass))
-#define GAIL_IS_PROGRESS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_PROGRESS_BAR))
-#define GAIL_IS_PROGRESS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_PROGRESS_BAR))
-#define GAIL_PROGRESS_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_PROGRESS_BAR, GailProgressBarClass))
-
-typedef struct _GailProgressBar GailProgressBar;
-typedef struct _GailProgressBarClass GailProgressBarClass;
-
-struct _GailProgressBar
-{
- GailWidget parent;
-};
-
-GType gail_progress_bar_get_type (void);
-
-struct _GailProgressBarClass
-{
- GailWidgetClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_PROGRESS_BAR_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailradiobutton.h"
-
-static void gail_radio_button_class_init (GailRadioButtonClass *klass);
-static void gail_radio_button_init (GailRadioButton *radio_button);
-static void gail_radio_button_initialize (AtkObject *accessible,
- gpointer data);
-
-static AtkRelationSet* gail_radio_button_ref_relation_set (AtkObject *obj);
-
-G_DEFINE_TYPE (GailRadioButton, gail_radio_button, GAIL_TYPE_TOGGLE_BUTTON)
-
-static void
-gail_radio_button_class_init (GailRadioButtonClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->initialize = gail_radio_button_initialize;
- class->ref_relation_set = gail_radio_button_ref_relation_set;
-}
-
-static void
-gail_radio_button_init (GailRadioButton *radio_button)
-{
- radio_button->old_group = NULL;
-}
-
-static void
-gail_radio_button_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_radio_button_parent_class)->initialize (accessible, data);
-
- accessible->role = ATK_ROLE_RADIO_BUTTON;
-}
-
-AtkRelationSet*
-gail_radio_button_ref_relation_set (AtkObject *obj)
-{
- GtkWidget *widget;
- AtkRelationSet *relation_set;
- GSList *list;
- GailRadioButton *radio_button;
-
- g_return_val_if_fail (GAIL_IS_RADIO_BUTTON (obj), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- {
- /*
- * State is defunct
- */
- return NULL;
- }
- radio_button = GAIL_RADIO_BUTTON (obj);
-
- relation_set = ATK_OBJECT_CLASS (gail_radio_button_parent_class)->ref_relation_set (obj);
-
- /*
- * If the radio button'group has changed remove the relation
- */
- list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
-
- if (radio_button->old_group != list)
- {
- AtkRelation *relation;
-
- relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_MEMBER_OF);
- atk_relation_set_remove (relation_set, relation);
- }
-
- if (!atk_relation_set_contains (relation_set, ATK_RELATION_MEMBER_OF))
- {
- /*
- * Get the members of the button group
- */
-
- radio_button->old_group = list;
- if (list)
- {
- AtkObject **accessible_array;
- guint list_length;
- AtkRelation* relation;
- gint i = 0;
-
- list_length = g_slist_length (list);
- accessible_array = (AtkObject**) g_malloc (sizeof (AtkObject *) *
- list_length);
- while (list != NULL)
- {
- GtkWidget* list_item = list->data;
-
- accessible_array[i++] = gtk_widget_get_accessible (list_item);
-
- list = list->next;
- }
- relation = atk_relation_new (accessible_array, list_length,
- ATK_RELATION_MEMBER_OF);
- g_free (accessible_array);
-
- atk_relation_set_add (relation_set, relation);
- /*
- * Unref the relation so that it is not leaked.
- */
- g_object_unref (relation);
- }
- }
- return relation_set;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_RADIO_BUTTON_H__
-#define __GAIL_RADIO_BUTTON_H__
-
-#include "gailtogglebutton.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_RADIO_BUTTON (gail_radio_button_get_type ())
-#define GAIL_RADIO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RADIO_BUTTON, GailRadioButton))
-#define GAIL_RADIO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RADIO_BUTTON, GailRadioButtonClass))
-#define GAIL_IS_RADIO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RADIO_BUTTON))
-#define GAIL_IS_RADIO_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RADIO_BUTTON))
-#define GAIL_RADIO_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RADIO_BUTTON, GailRadioButtonClass))
-
-typedef struct _GailRadioButton GailRadioButton;
-typedef struct _GailRadioButtonClass GailRadioButtonClass;
-
-struct _GailRadioButton
-{
- GailToggleButton parent;
-
- GSList *old_group;
-};
-
-GType gail_radio_button_get_type (void);
-
-struct _GailRadioButtonClass
-{
- GailToggleButtonClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_RADIO_BUTTON_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailradiomenuitem.h"
-#include "gailradiosubmenuitem.h"
-
-static void gail_radio_menu_item_class_init (GailRadioMenuItemClass *klass);
-static void gail_radio_menu_item_init (GailRadioMenuItem *radio_menu_item);
-
-static AtkRelationSet* gail_radio_menu_item_ref_relation_set (AtkObject *obj);
-
-G_DEFINE_TYPE (GailRadioMenuItem, gail_radio_menu_item, GAIL_TYPE_CHECK_MENU_ITEM)
-
-static void
-gail_radio_menu_item_class_init (GailRadioMenuItemClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->ref_relation_set = gail_radio_menu_item_ref_relation_set;
-}
-
-AtkObject*
-gail_radio_menu_item_new (GtkWidget *widget)
-{
- GObject *object;
- AtkObject *accessible;
-
- g_return_val_if_fail (GTK_IS_RADIO_MENU_ITEM (widget), NULL);
-
- if (gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)))
- return gail_radio_sub_menu_item_new (widget);
-
- object = g_object_new (GAIL_TYPE_RADIO_MENU_ITEM, NULL);
-
- accessible = ATK_OBJECT (object);
- atk_object_initialize (accessible, widget);
-
- accessible->role = ATK_ROLE_RADIO_MENU_ITEM;
- return accessible;
-}
-
-static void
-gail_radio_menu_item_init (GailRadioMenuItem *radio_menu_item)
-{
- radio_menu_item->old_group = NULL;
-}
-
-AtkRelationSet*
-gail_radio_menu_item_ref_relation_set (AtkObject *obj)
-{
- GtkWidget *widget;
- AtkRelationSet *relation_set;
- GSList *list;
- GailRadioMenuItem *radio_menu_item;
-
- g_return_val_if_fail (GAIL_IS_RADIO_MENU_ITEM (obj), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- {
- /*
- * State is defunct
- */
- return NULL;
- }
- radio_menu_item = GAIL_RADIO_MENU_ITEM (obj);
-
- relation_set = ATK_OBJECT_CLASS (gail_radio_menu_item_parent_class)->ref_relation_set (obj);
-
- /*
- * If the radio menu_item'group has changed remove the relation
- */
- list = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget));
-
- if (radio_menu_item->old_group != list)
- {
- AtkRelation *relation;
-
- relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_MEMBER_OF);
- atk_relation_set_remove (relation_set, relation);
- }
-
- if (!atk_relation_set_contains (relation_set, ATK_RELATION_MEMBER_OF))
- {
- /*
- * Get the members of the menu_item group
- */
-
- radio_menu_item->old_group = list;
- if (list)
- {
- AtkObject **accessible_array;
- guint list_length;
- AtkRelation* relation;
- gint i = 0;
-
- list_length = g_slist_length (list);
- accessible_array = (AtkObject**) g_malloc (sizeof (AtkObject *) *
- list_length);
- while (list != NULL)
- {
- GtkWidget* list_item = list->data;
-
- accessible_array[i++] = gtk_widget_get_accessible (list_item);
-
- list = list->next;
- }
- relation = atk_relation_new (accessible_array, list_length,
- ATK_RELATION_MEMBER_OF);
- g_free (accessible_array);
-
- atk_relation_set_add (relation_set, relation);
- /*
- * Unref the relation so that it is not leaked.
- */
- g_object_unref (relation);
- }
- }
- return relation_set;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_RADIO_MENU_ITEM_H__
-#define __GAIL_RADIO_MENU_ITEM_H__
-
-#include "gailcheckmenuitem.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_RADIO_MENU_ITEM (gail_radio_menu_item_get_type ())
-#define GAIL_RADIO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RADIO_MENU_ITEM, GailRadioMenuItem))
-#define GAIL_RADIO_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RADIO_MENU_ITEM, GailRadioMenuItemClass))
-#define GAIL_IS_RADIO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RADIO_MENU_ITEM))
-#define GAIL_IS_RADIO_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RADIO_MENU_ITEM))
-#define GAIL_RADIO_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RADIO_MENU_ITEM, GailRadioMenuItemClass))
-
-typedef struct _GailRadioMenuItem GailRadioMenuItem;
-typedef struct _GailRadioMenuItemClass GailRadioMenuItemClass;
-
-struct _GailRadioMenuItem
-{
- GailCheckMenuItem parent;
-
- GSList *old_group;
-};
-
-GType gail_radio_menu_item_get_type (void);
-
-struct _GailRadioMenuItemClass
-{
- GailCheckMenuItemClass parent_class;
-};
-
-AtkObject* gail_radio_menu_item_new (GtkWidget *widget);
-
-G_END_DECLS
-
-#endif /* __GAIL_RADIO_MENU_ITEM_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailradiosubmenuitem.h"
-
-static void gail_radio_sub_menu_item_class_init (GailRadioSubMenuItemClass *klass);
-static void gail_radio_sub_menu_item_init (GailRadioSubMenuItem *radio_menu_item);
-
-static AtkRelationSet* gail_radio_sub_menu_item_ref_relation_set (AtkObject *obj);
-
-G_DEFINE_TYPE (GailRadioSubMenuItem, gail_radio_sub_menu_item, GAIL_TYPE_CHECK_SUB_MENU_ITEM)
-
-static void
-gail_radio_sub_menu_item_class_init (GailRadioSubMenuItemClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->ref_relation_set = gail_radio_sub_menu_item_ref_relation_set;
-}
-
-AtkObject*
-gail_radio_sub_menu_item_new (GtkWidget *widget)
-{
- GObject *object;
- AtkObject *accessible;
-
- g_return_val_if_fail (GTK_IS_RADIO_MENU_ITEM (widget), NULL);
-
- object = g_object_new (GAIL_TYPE_RADIO_SUB_MENU_ITEM, NULL);
-
- accessible = ATK_OBJECT (object);
- atk_object_initialize (accessible, widget);
-
- accessible->role = ATK_ROLE_RADIO_MENU_ITEM;
- return accessible;
-}
-
-static void
-gail_radio_sub_menu_item_init (GailRadioSubMenuItem *radio_menu_item)
-{
- radio_menu_item->old_group = NULL;
-}
-
-AtkRelationSet*
-gail_radio_sub_menu_item_ref_relation_set (AtkObject *obj)
-{
- GtkWidget *widget;
- AtkRelationSet *relation_set;
- GSList *list;
- GailRadioSubMenuItem *radio_menu_item;
-
- g_return_val_if_fail (GAIL_IS_RADIO_SUB_MENU_ITEM (obj), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- {
- /*
- * State is defunct
- */
- return NULL;
- }
- radio_menu_item = GAIL_RADIO_SUB_MENU_ITEM (obj);
-
- relation_set = ATK_OBJECT_CLASS (gail_radio_sub_menu_item_parent_class)->ref_relation_set (obj);
-
- /*
- * If the radio menu_item'group has changed remove the relation
- */
- list = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget));
-
- if (radio_menu_item->old_group != list)
- {
- AtkRelation *relation;
-
- relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_MEMBER_OF);
- atk_relation_set_remove (relation_set, relation);
- }
-
- if (!atk_relation_set_contains (relation_set, ATK_RELATION_MEMBER_OF))
- {
- /*
- * Get the members of the menu_item group
- */
-
- radio_menu_item->old_group = list;
- if (list)
- {
- AtkObject **accessible_array;
- guint list_length;
- AtkRelation* relation;
- gint i = 0;
-
- list_length = g_slist_length (list);
- accessible_array = (AtkObject**) g_malloc (sizeof (AtkObject *) *
- list_length);
- while (list != NULL)
- {
- GtkWidget* list_item = list->data;
-
- accessible_array[i++] = gtk_widget_get_accessible (list_item);
-
- list = list->next;
- }
- relation = atk_relation_new (accessible_array, list_length,
- ATK_RELATION_MEMBER_OF);
- g_free (accessible_array);
-
- atk_relation_set_add (relation_set, relation);
- /*
- * Unref the relation so that it is not leaked.
- */
- g_object_unref (relation);
- }
- }
- return relation_set;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_RADIO_SUB_MENU_ITEM_H__
-#define __GAIL_RADIO_SUB_MENU_ITEM_H__
-
-#include "gailchecksubmenuitem.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_RADIO_SUB_MENU_ITEM (gail_radio_sub_menu_item_get_type ())
-#define GAIL_RADIO_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RADIO_SUB_MENU_ITEM, GailRadioSubMenuItem))
-#define GAIL_RADIO_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RADIO_SUB_MENU_ITEM, GailRadioSubMenuItemClass))
-#define GAIL_IS_RADIO_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RADIO_SUB_MENU_ITEM))
-#define GAIL_IS_RADIO_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RADIO_SUB_MENU_ITEM))
-#define GAIL_RADIO_SUB_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RADIO_SUB_MENU_ITEM, GailRadioSubMenuItemClass))
-
-typedef struct _GailRadioSubMenuItem GailRadioSubMenuItem;
-typedef struct _GailRadioSubMenuItemClass GailRadioSubMenuItemClass;
-
-struct _GailRadioSubMenuItem
-{
- GailCheckSubMenuItem parent;
-
- GSList *old_group;
-};
-
-GType gail_radio_sub_menu_item_get_type (void);
-
-struct _GailRadioSubMenuItemClass
-{
- GailCheckSubMenuItemClass parent_class;
-};
-
-AtkObject* gail_radio_sub_menu_item_new (GtkWidget *widget);
-
-G_END_DECLS
-
-#endif /* __GAIL_RADIO_SUB_MENU_ITEM_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "gailrange.h"
-#include "gailadjustment.h"
-#include "gail-private-macros.h"
-
-static void gail_range_class_init (GailRangeClass *klass);
-
-static void gail_range_init (GailRange *range);
-
-static void gail_range_real_initialize (AtkObject *obj,
- gpointer data);
-
-static void gail_range_finalize (GObject *object);
-
-static void gail_range_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-
-static void atk_value_interface_init (AtkValueIface *iface);
-static void gail_range_get_current_value (AtkValue *obj,
- GValue *value);
-static void gail_range_get_maximum_value (AtkValue *obj,
- GValue *value);
-static void gail_range_get_minimum_value (AtkValue *obj,
- GValue *value);
-static void gail_range_get_minimum_increment (AtkValue *obj,
- GValue *value);
-static gboolean gail_range_set_current_value (AtkValue *obj,
- const GValue *value);
-static void gail_range_value_changed (GtkAdjustment *adjustment,
- gpointer data);
-
-static void atk_action_interface_init (AtkActionIface *iface);
-static gboolean gail_range_do_action (AtkAction *action,
- gint i);
-static gboolean idle_do_action (gpointer data);
-static gint gail_range_get_n_actions (AtkAction *action);
-static const gchar* gail_range_get_description (AtkAction *action,
- gint i);
-static const gchar* gail_range_get_keybinding (AtkAction *action,
- gint i);
-static const gchar* gail_range_action_get_name (AtkAction *action,
- gint i);
-static gboolean gail_range_set_description (AtkAction *action,
- gint i,
- const gchar *desc);
-
-G_DEFINE_TYPE_WITH_CODE (GailRange, gail_range, GAIL_TYPE_WIDGET,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
-
-static void
-gail_range_class_init (GailRangeClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailWidgetClass *widget_class;
-
- widget_class = (GailWidgetClass*)klass;
-
- widget_class->notify_gtk = gail_range_real_notify_gtk;
-
- class->initialize = gail_range_real_initialize;
-
- gobject_class->finalize = gail_range_finalize;
-}
-
-static void
-gail_range_init (GailRange *range)
-{
-}
-
-static void
-gail_range_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GailRange *range = GAIL_RANGE (obj);
- GtkAdjustment *adj;
- GtkRange *gtk_range;
-
- ATK_OBJECT_CLASS (gail_range_parent_class)->initialize (obj, data);
-
- gtk_range = GTK_RANGE (data);
- /*
- * If a GtkAdjustment already exists for the GtkRange,
- * create the GailAdjustment
- */
- adj = gtk_range_get_adjustment (gtk_range);
- if (adj)
- {
- range->adjustment = gail_adjustment_new (adj);
- g_signal_connect (adj,
- "value-changed",
- G_CALLBACK (gail_range_value_changed),
- range);
- }
- else
- range->adjustment = NULL;
- range->activate_keybinding=NULL;
- range->activate_description=NULL;
- /*
- * Assumed to GtkScale (either GtkHScale or GtkVScale)
- */
- obj->role = ATK_ROLE_SLIDER;
-}
-
-static void
-atk_value_interface_init (AtkValueIface *iface)
-{
- iface->get_current_value = gail_range_get_current_value;
- iface->get_maximum_value = gail_range_get_maximum_value;
- iface->get_minimum_value = gail_range_get_minimum_value;
- iface->get_minimum_increment = gail_range_get_minimum_increment;
- iface->set_current_value = gail_range_set_current_value;
-}
-
-static void
-gail_range_get_current_value (AtkValue *obj,
- GValue *value)
-{
- GailRange *range;
-
- g_return_if_fail (GAIL_IS_RANGE (obj));
-
- range = GAIL_RANGE (obj);
- if (range->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_current_value (ATK_VALUE (range->adjustment), value);
-}
-
-static void
-gail_range_get_maximum_value (AtkValue *obj,
- GValue *value)
-{
- GailRange *range;
- GtkRange *gtk_range;
- GtkAdjustment *gtk_adjustment;
- gdouble max = 0;
-
- g_return_if_fail (GAIL_IS_RANGE (obj));
-
- range = GAIL_RANGE (obj);
- if (range->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_maximum_value (ATK_VALUE (range->adjustment), value);
-
- gtk_range = GTK_RANGE (gtk_accessible_get_widget (GTK_ACCESSIBLE (range)));
- g_return_if_fail (gtk_range);
-
- gtk_adjustment = gtk_range_get_adjustment (gtk_range);
- max = g_value_get_double (value);
- max -= gtk_adjustment_get_page_size (gtk_adjustment);
-
- if (gtk_range_get_restrict_to_fill_level (gtk_range))
- max = MIN (max, gtk_range_get_fill_level (gtk_range));
-
- g_value_set_double (value, max);
-}
-
-static void
-gail_range_get_minimum_value (AtkValue *obj,
- GValue *value)
-{
- GailRange *range;
-
- g_return_if_fail (GAIL_IS_RANGE (obj));
-
- range = GAIL_RANGE (obj);
- if (range->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_minimum_value (ATK_VALUE (range->adjustment), value);
-}
-
-static void
-gail_range_get_minimum_increment (AtkValue *obj, GValue *value)
-{
- GailRange *range;
-
- g_return_if_fail (GAIL_IS_RANGE (obj));
-
- range = GAIL_RANGE (obj);
- if (range->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_minimum_increment (ATK_VALUE (range->adjustment), value);
-}
-
-static gboolean gail_range_set_current_value (AtkValue *obj,
- const GValue *value)
-{
- GtkWidget *widget;
-
- g_return_val_if_fail (GAIL_IS_RANGE (obj), FALSE);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return FALSE;
-
- if (G_VALUE_HOLDS_DOUBLE (value))
- {
- GtkRange *range = GTK_RANGE (widget);
- gdouble new_value;
-
- new_value = g_value_get_double (value);
- gtk_range_set_value (range, new_value);
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-static void
-gail_range_finalize (GObject *object)
-{
- GailRange *range = GAIL_RANGE (object);
-
- if (range->adjustment)
- {
- /*
- * The GtkAdjustment may live on so we need to dicsonnect the
- * signal handler
- */
- if (GAIL_ADJUSTMENT (range->adjustment)->adjustment)
- {
- g_signal_handlers_disconnect_by_func (GAIL_ADJUSTMENT (range->adjustment)->adjustment,
- (void *)gail_range_value_changed,
- range);
- }
- g_object_unref (range->adjustment);
- range->adjustment = NULL;
- }
- range->activate_keybinding=NULL;
- range->activate_description=NULL;
- if (range->action_idle_handler)
- {
- g_source_remove (range->action_idle_handler);
- range->action_idle_handler = 0;
- }
-
- G_OBJECT_CLASS (gail_range_parent_class)->finalize (object);
-}
-
-
-static void
-gail_range_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkAdjustment *adj;
- GtkWidget *widget = GTK_WIDGET (obj);
- GailRange *range = GAIL_RANGE (gtk_widget_get_accessible (widget));
-
- if (strcmp (pspec->name, "adjustment") == 0)
- {
- /*
- * Get rid of the GailAdjustment for the GtkAdjustment
- * which was associated with the range.
- */
- if (range->adjustment)
- {
- g_object_unref (range->adjustment);
- range->adjustment = NULL;
- }
- /*
- * Create the GailAdjustment when notify for "adjustment" property
- * is received
- */
- adj = gtk_range_get_adjustment (GTK_RANGE (widget));
- range->adjustment = gail_adjustment_new (adj);
- g_signal_connect (adj,
- "value-changed",
- G_CALLBACK (gail_range_value_changed),
- range);
- }
- else
- GAIL_WIDGET_CLASS (gail_range_parent_class)->notify_gtk (obj, pspec);
-}
-
-static void
-gail_range_value_changed (GtkAdjustment *adjustment,
- gpointer data)
-{
- GailRange *range;
-
- g_return_if_fail (adjustment != NULL);
- gail_return_if_fail (data != NULL);
-
- range = GAIL_RANGE (data);
-
- g_object_notify (G_OBJECT (range), "accessible-value");
-}
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- iface->do_action = gail_range_do_action;
- iface->get_n_actions = gail_range_get_n_actions;
- iface->get_description = gail_range_get_description;
- iface->get_keybinding = gail_range_get_keybinding;
- iface->get_name = gail_range_action_get_name;
- iface->set_description = gail_range_set_description;
-}
-
-static gboolean
-gail_range_do_action (AtkAction *action,
- gint i)
-{
- GailRange *range;
- GtkWidget *widget;
- gboolean return_value = TRUE;
-
- range = GAIL_RANGE (action);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return FALSE;
- if (!gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
- if(i==0)
- {
- if (range->action_idle_handler)
- return_value = FALSE;
- else
- range->action_idle_handler = gdk_threads_add_idle (idle_do_action, range);
- }
- else
- return_value = FALSE;
- return return_value;
-}
-
-static gboolean
-idle_do_action (gpointer data)
-{
- GailRange *range;
- GtkWidget *widget;
-
- range = GAIL_RANGE (data);
- range->action_idle_handler = 0;
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (range));
- if (widget == NULL /* State is defunct */ ||
- !gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- gtk_widget_activate (widget);
-
- return FALSE;
-}
-
-static gint
-gail_range_get_n_actions (AtkAction *action)
-{
- return 1;
-}
-
-static const gchar*
-gail_range_get_description (AtkAction *action,
- gint i)
-{
- GailRange *range;
- const gchar *return_value;
-
- range = GAIL_RANGE (action);
- if (i==0)
- return_value = range->activate_description;
- else
- return_value = NULL;
- return return_value;
-}
-
-static const gchar*
-gail_range_get_keybinding (AtkAction *action,
- gint i)
-{
- GailRange *range;
- gchar *return_value = NULL;
- range = GAIL_RANGE (action);
- if(i==0)
- {
- GtkWidget *widget;
- GtkWidget *label;
- AtkRelationSet *set;
- AtkRelation *relation;
- GPtrArray *target;
- gpointer target_object;
- guint key_val;
-
- range = GAIL_RANGE (action);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (range));
- if (widget == NULL)
- return NULL;
- set = atk_object_ref_relation_set (ATK_OBJECT (action));
-
- if (!set)
- return NULL;
- label = NULL;
- relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
- if (relation)
- {
- target = atk_relation_get_target (relation);
- target_object = g_ptr_array_index (target, 0);
- label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
- }
- g_object_unref (set);
- if (GTK_IS_LABEL (label))
- {
- key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
- if (key_val != GDK_KEY_VoidSymbol)
- return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
- }
- g_free (range->activate_keybinding);
- range->activate_keybinding = return_value;
- }
- return return_value;
-}
-
-static const gchar*
-gail_range_action_get_name (AtkAction *action,
- gint i)
-{
- const gchar *return_value;
-
- if (i==0)
- return_value = "activate";
- else
- return_value = NULL;
-
- return return_value;
-}
-
-static gboolean
-gail_range_set_description (AtkAction *action,
- gint i,
- const gchar *desc)
-{
- GailRange *range;
- gchar **value;
-
- range = GAIL_RANGE (action);
-
- if (i==0)
- value = &range->activate_description;
- else
- value = NULL;
-
- if (value)
- {
- g_free (*value);
- *value = g_strdup (desc);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_RANGE_H__
-#define __GAIL_RANGE_H__
-
-#include "gailwidget.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_RANGE (gail_range_get_type ())
-#define GAIL_RANGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RANGE, GailRange))
-#define GAIL_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RANGE, GailRangeClass))
-#define GAIL_IS_RANGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RANGE))
-#define GAIL_IS_RANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RANGE))
-#define GAIL_RANGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RANGE, GailRangeClass))
-
-typedef struct _GailRange GailRange;
-typedef struct _GailRangeClass GailRangeClass;
-
-struct _GailRange
-{
- GailWidget parent;
-
- AtkObject *adjustment;
- gchar *activate_description;
- gchar *activate_keybinding;
- guint action_idle_handler;
-
-};
-
-GType gail_range_get_type (void);
-
-struct _GailRangeClass
-{
- GailWidgetClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_RANGE_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailrenderercell.h"
-
-static void gail_renderer_cell_class_init (GailRendererCellClass *klass);
-static void gail_renderer_cell_init (GailRendererCell *renderer_cell);
-
-static void gail_renderer_cell_finalize (GObject *object);
-
-G_DEFINE_TYPE (GailRendererCell, gail_renderer_cell, GAIL_TYPE_CELL)
-
-static void
-gail_renderer_cell_class_init (GailRendererCellClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- klass->property_list = NULL;
-
- gobject_class->finalize = gail_renderer_cell_finalize;
-}
-
-static void
-gail_renderer_cell_init (GailRendererCell *renderer_cell)
-{
- renderer_cell->renderer = NULL;
-}
-
-static void
-gail_renderer_cell_finalize (GObject *object)
-{
- GailRendererCell *renderer_cell = GAIL_RENDERER_CELL (object);
-
- if (renderer_cell->renderer)
- g_object_unref (renderer_cell->renderer);
- G_OBJECT_CLASS (gail_renderer_cell_parent_class)->finalize (object);
-}
-
-gboolean
-gail_renderer_cell_update_cache (GailRendererCell *cell,
- gboolean emit_change_signal)
-{
- GailRendererCellClass *class = GAIL_RENDERER_CELL_GET_CLASS(cell);
- if (class->update_cache)
- return (class->update_cache)(cell, emit_change_signal);
- return FALSE;
-}
-
-AtkObject*
-gail_renderer_cell_new (void)
-{
- GObject *object;
- AtkObject *atk_object;
-
- object = g_object_new (GAIL_TYPE_RENDERER_CELL, NULL);
-
- g_return_val_if_fail (object != NULL, NULL);
-
- atk_object = ATK_OBJECT (object);
- atk_object->role = ATK_ROLE_TABLE_CELL;
-
- return atk_object;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_RENDERER_CELL_H__
-#define __GAIL_RENDERER_CELL_H__
-
-#include <atk/atk.h>
-#include "gailcell.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_RENDERER_CELL (gail_renderer_cell_get_type ())
-#define GAIL_RENDERER_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_RENDERER_CELL, GailRendererCell))
-#define GAIL_RENDERER_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_RENDERER_CELL, GailRendererCellClass))
-#define GAIL_IS_RENDERER_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_RENDERER_CELL))
-#define GAIL_IS_RENDERER_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_RENDERER_CELL))
-#define GAIL_RENDERER_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_RENDERER_CELL, GailRendererCellClass))
-
-typedef struct _GailRendererCell GailRendererCell;
-typedef struct _GailRendererCellClass GailRendererCellClass;
-
-struct _GailRendererCell
-{
- GailCell parent;
- GtkCellRenderer *renderer;
-};
-
-GType gail_renderer_cell_get_type (void);
-
-struct _GailRendererCellClass
-{
- GailCellClass parent_class;
- gchar **property_list;
- gboolean (*update_cache)(GailRendererCell *cell, gboolean emit_change_signal);
-};
-
-gboolean
-gail_renderer_cell_update_cache (GailRendererCell *cell, gboolean emit_change_signal);
-
-AtkObject *gail_renderer_cell_new (void);
-
-G_END_DECLS
-
-#endif /* __GAIL_TREE_VIEW_TEXT_CELL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2004 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailscale.h"
-#include <libgail-util/gailmisc.h>
-
-static void gail_scale_class_init (GailScaleClass *klass);
-
-static void gail_scale_init (GailScale *scale);
-
-static void gail_scale_real_initialize (AtkObject *obj,
- gpointer data);
-static void gail_scale_notify (GObject *obj,
- GParamSpec *pspec);
-static void gail_scale_finalize (GObject *object);
-
-/* atktext.h */
-static void atk_text_interface_init (AtkTextIface *iface);
-
-static gchar* gail_scale_get_text (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gunichar gail_scale_get_character_at_offset
- (AtkText *text,
- gint offset);
-static gchar* gail_scale_get_text_before_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_scale_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_scale_get_text_after_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gint gail_scale_get_character_count (AtkText *text);
-static void gail_scale_get_character_extents
- (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static gint gail_scale_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static AtkAttributeSet* gail_scale_get_run_attributes
- (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet* gail_scale_get_default_attributes
- (AtkText *text);
-
-G_DEFINE_TYPE_WITH_CODE (GailScale, gail_scale, GAIL_TYPE_RANGE,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
-
-static void
-gail_scale_class_init (GailScaleClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->initialize = gail_scale_real_initialize;
-
- gobject_class->finalize = gail_scale_finalize;
- gobject_class->notify = gail_scale_notify;
-}
-
-static void
-gail_scale_init (GailScale *scale)
-{
-}
-
-static void
-gail_scale_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GailScale *gail_scale;
- const gchar *txt;
- PangoLayout *layout;
-
- ATK_OBJECT_CLASS (gail_scale_parent_class)->initialize (obj, data);
-
- gail_scale = GAIL_SCALE (obj);
- gail_scale->textutil = gail_text_util_new ();
-
- layout = gtk_scale_get_layout (GTK_SCALE (data));
- if (layout)
- {
- txt = pango_layout_get_text (layout);
- if (txt)
- {
- gail_text_util_text_setup (gail_scale->textutil, txt);
- }
- }
-}
-
-static void
-gail_scale_finalize (GObject *object)
-{
- GailScale *scale = GAIL_SCALE (object);
-
- g_object_unref (scale->textutil);
- G_OBJECT_CLASS (gail_scale_parent_class)->finalize (object);
-
-}
-
-static void
-gail_scale_notify (GObject *obj,
- GParamSpec *pspec)
-{
- GailScale *scale = GAIL_SCALE (obj);
-
- if (strcmp (pspec->name, "accessible-value") == 0)
- {
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget)
- {
- GtkScale *gtk_scale;
- PangoLayout *layout;
- const gchar *txt;
-
- gtk_scale = GTK_SCALE (widget);
- layout = gtk_scale_get_layout (gtk_scale);
- if (layout)
- {
- txt = pango_layout_get_text (layout);
- if (txt)
- {
- g_signal_emit_by_name (obj, "text_changed::delete", 0,
- gtk_text_buffer_get_char_count (scale->textutil->buffer));
- gail_text_util_text_setup (scale->textutil, txt);
- g_signal_emit_by_name (obj, "text_changed::insert", 0,
- g_utf8_strlen (txt, -1));
- }
- }
- }
- }
- G_OBJECT_CLASS (gail_scale_parent_class)->notify (obj, pspec);
-}
-
-/* atktext.h */
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_scale_get_text;
- iface->get_character_at_offset = gail_scale_get_character_at_offset;
- iface->get_text_before_offset = gail_scale_get_text_before_offset;
- iface->get_text_at_offset = gail_scale_get_text_at_offset;
- iface->get_text_after_offset = gail_scale_get_text_after_offset;
- iface->get_character_count = gail_scale_get_character_count;
- iface->get_character_extents = gail_scale_get_character_extents;
- iface->get_offset_at_point = gail_scale_get_offset_at_point;
- iface->get_run_attributes = gail_scale_get_run_attributes;
- iface->get_default_attributes = gail_scale_get_default_attributes;
-}
-
-static gchar*
-gail_scale_get_text (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *widget;
- GailScale *scale;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- scale = GAIL_SCALE (text);
- return gail_text_util_get_substring (scale->textutil,
- start_pos, end_pos);
-}
-
-static gchar*
-gail_scale_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GailScale *scale;
- PangoLayout *layout;
- gchar *txt;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- scale = GAIL_SCALE (text);
- layout = gtk_scale_get_layout (GTK_SCALE (widget));
- if (layout)
- {
- txt = gail_text_util_get_text (scale->textutil,
- layout, GAIL_BEFORE_OFFSET,
- boundary_type, offset, start_offset, end_offset);
- }
- else
- txt = NULL;
-
- return txt;
-}
-
-static gchar*
-gail_scale_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GailScale *scale;
- PangoLayout *layout;
- gchar *txt;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- scale = GAIL_SCALE (text);
- layout = gtk_scale_get_layout (GTK_SCALE (widget));
- if (layout)
- {
- txt = gail_text_util_get_text (scale->textutil,
- layout, GAIL_AT_OFFSET,
- boundary_type, offset, start_offset, end_offset);
- }
- else
- txt = NULL;
-
- return txt;
-}
-
-static gchar*
-gail_scale_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GailScale *scale;
- PangoLayout *layout;
- gchar *txt;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- scale = GAIL_SCALE (text);
- layout = gtk_scale_get_layout (GTK_SCALE (widget));
- if (layout)
- {
- txt = gail_text_util_get_text (scale->textutil,
- layout, GAIL_AFTER_OFFSET,
- boundary_type, offset, start_offset, end_offset);
- }
- else
- txt = NULL;
-
- return txt;
-}
-
-static gint
-gail_scale_get_character_count (AtkText *text)
-{
- GtkWidget *widget;
- GailScale *scale;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- scale = GAIL_SCALE (text);
- if (scale->textutil->buffer)
- return gtk_text_buffer_get_char_count (scale->textutil->buffer);
- else
- return 0;
-
-}
-
-static void
-gail_scale_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkScale *scale;
- PangoRectangle char_rect;
- PangoLayout *layout;
- gint index, x_layout, y_layout;
- const gchar *scale_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return;
-
- scale = GTK_SCALE (widget);
- layout = gtk_scale_get_layout (scale);
- if (!layout)
- return;
- scale_text = pango_layout_get_text (layout);
- if (!scale_text)
- return;
- index = g_utf8_offset_to_pointer (scale_text, offset) - scale_text;
- gtk_scale_get_layout_offsets (scale, &x_layout, &y_layout);
- pango_layout_index_to_pos (layout, index, &char_rect);
- gail_misc_get_extents_from_pango_rectangle (widget, &char_rect,
- x_layout, y_layout, x, y, width, height, coords);
-}
-
-static gint
-gail_scale_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkScale *scale;
- PangoLayout *layout;
- gint index, x_layout, y_layout;
- const gchar *scale_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- scale = GTK_SCALE (widget);
- layout = gtk_scale_get_layout (scale);
- if (!layout)
- return -1;
- scale_text = pango_layout_get_text (layout);
- if (!scale_text)
- return -1;
-
- gtk_scale_get_layout_offsets (scale, &x_layout, &y_layout);
- index = gail_misc_get_index_at_point_in_layout (widget,
- layout,
- x_layout, y_layout, x, y, coords);
- if (index == -1)
- {
- if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
- index = g_utf8_strlen (scale_text, -1);
- }
- else
- index = g_utf8_pointer_to_offset (scale_text, scale_text + index);
-
- return index;
-}
-
-static AtkAttributeSet*
-gail_scale_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkScale *scale;
- AtkAttributeSet *at_set = NULL;
- GtkTextDirection dir;
- PangoLayout *layout;
- const gchar *scale_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- scale = GTK_SCALE (widget);
-
- layout = gtk_scale_get_layout (scale);
- if (!layout)
- return at_set;
- scale_text = pango_layout_get_text (layout);
- if (!scale_text)
- return at_set;
-
- dir = gtk_widget_get_direction (widget);
- if (dir == GTK_TEXT_DIR_RTL)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_DIRECTION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
- }
-
- at_set = gail_misc_layout_get_run_attributes (at_set,
- layout,
- (gchar *)scale_text,
- offset,
- start_offset,
- end_offset);
- return at_set;
-}
-
-static AtkAttributeSet*
-gail_scale_get_default_attributes (AtkText *text)
-{
- GtkWidget *widget;
- AtkAttributeSet *at_set = NULL;
- PangoLayout *layout;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- layout = gtk_scale_get_layout (GTK_SCALE (widget));
- if (layout)
- {
- at_set = gail_misc_get_default_attributes (at_set,
- layout,
- widget);
- }
- return at_set;
-}
-
-static gunichar
-gail_scale_get_character_at_offset (AtkText *text,
- gint offset)
-{
- GtkWidget *widget;
- GtkScale *scale;
- PangoLayout *layout;
- const gchar *string;
- gchar *index;
- gunichar c;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return '\0';
-
- scale = GTK_SCALE (widget);
-
- layout = gtk_scale_get_layout (scale);
- if (!layout)
- return '\0';
- string = pango_layout_get_text (layout);
- if (offset >= g_utf8_strlen (string, -1))
- c = '\0';
- else
- {
- index = g_utf8_offset_to_pointer (string, offset);
-
- c = g_utf8_get_char (index);
- }
-
- return c;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2004 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_SCALE_H__
-#define __GAIL_SCALE_H__
-
-#include "gailrange.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_SCALE (gail_scale_get_type ())
-#define GAIL_SCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SCALE, GailScale))
-#define GAIL_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SCALE, GailScaleClass))
-#define GAIL_IS_SCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SCALE))
-#define GAIL_IS_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SCALE))
-#define GAIL_SCALE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SCALE, GailScaleClass))
-
-typedef struct _GailScale GailScale;
-typedef struct _GailScaleClass GailScaleClass;
-
-struct _GailScale
-{
- GailRange parent;
-
- GailTextUtil *textutil;
-};
-
-GType gail_scale_get_type (void);
-
-struct _GailScaleClass
-{
- GailRangeClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_SCALE_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2008 Jan Arne Petersen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-
-#include <gtk/gtk.h>
-#include "gailscalebutton.h"
-#include "gailadjustment.h"
-#include "gail-private-macros.h"
-
-#include <string.h>
-
-static void gail_scale_button_class_init (GailScaleButtonClass *klass);
-static void gail_scale_button_init (GailScaleButton *button);
-
-/* GailWidget */
-static void gail_scale_button_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-
-/* AtkObject */
-static void gail_scale_button_real_initialize (AtkObject *obj,
- gpointer data);
-
-/* AtkAction */
-static void atk_action_interface_init (AtkActionIface *iface);
-static gboolean gail_scale_button_do_action (AtkAction *action,
- gint i);
-static gint gail_scale_button_get_n_actions (AtkAction *action);
-static const gchar* gail_scale_button_get_description(AtkAction *action,
- gint i);
-static const gchar* gail_scale_button_action_get_name(AtkAction *action,
- gint i);
-static const gchar* gail_scale_button_get_keybinding (AtkAction *action,
- gint i);
-static gboolean gail_scale_button_set_description(AtkAction *action,
- gint i,
- const gchar *desc);
-
-/* AtkValue */
-static void atk_value_interface_init (AtkValueIface *iface);
-static void gail_scale_button_get_current_value (AtkValue *obj,
- GValue *value);
-static void gail_scale_button_get_maximum_value (AtkValue *obj,
- GValue *value);
-static void gail_scale_button_get_minimum_value (AtkValue *obj,
- GValue *value);
-static void gail_scale_button_get_minimum_increment (AtkValue *obj,
- GValue *value);
-static gboolean gail_scale_button_set_current_value (AtkValue *obj,
- const GValue *value);
-static void gail_scale_button_value_changed (GtkAdjustment *adjustment,
- gpointer data);
-
-G_DEFINE_TYPE_WITH_CODE (GailScaleButton, gail_scale_button, GAIL_TYPE_BUTTON,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init));
-
-static void
-gail_scale_button_class_init (GailScaleButtonClass *klass)
-{
- AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
- GailWidgetClass *widget_class = GAIL_WIDGET_CLASS (klass);
-
- atk_object_class->initialize = gail_scale_button_real_initialize;
-
- widget_class->notify_gtk = gail_scale_button_real_notify_gtk;
-}
-
-static void
-gail_scale_button_init (GailScaleButton *button)
-{
-}
-
-static void
-gail_scale_button_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GailScaleButton *scale_button = GAIL_SCALE_BUTTON (obj);
- GtkScaleButton *gtk_scale_button;
- GtkAdjustment *gtk_adjustment;
-
- ATK_OBJECT_CLASS (gail_scale_button_parent_class)->initialize (obj, data);
-
- gtk_scale_button = GTK_SCALE_BUTTON (data);
- gtk_adjustment = gtk_scale_button_get_adjustment (gtk_scale_button);
- /*
- * If a GtkAdjustment already exists for the scale_button,
- * create the GailAdjustment
- */
- if (gtk_adjustment)
- {
- scale_button->adjustment = gail_adjustment_new (gtk_adjustment);
- g_signal_connect (gtk_adjustment,
- "value-changed",
- G_CALLBACK (gail_scale_button_value_changed),
- obj);
- }
- else
- scale_button->adjustment = NULL;
-
- obj->role = ATK_ROLE_SLIDER;
-}
-
-static void
-atk_action_interface_init (AtkActionIface *iface)
-{
- iface->do_action = gail_scale_button_do_action;
- iface->get_n_actions = gail_scale_button_get_n_actions;
- iface->get_description = gail_scale_button_get_description;
- iface->get_keybinding = gail_scale_button_get_keybinding;
- iface->get_name = gail_scale_button_action_get_name;
- iface->set_description = gail_scale_button_set_description;
-}
-
-static gboolean
-gail_scale_button_do_action(AtkAction *action,
- gint i)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
- if (widget == NULL)
- return FALSE;
-
- if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
- return FALSE;
-
- switch (i) {
- case 0:
- g_signal_emit_by_name (widget, "popup");
- return TRUE;
- case 1:
- g_signal_emit_by_name (widget, "podown");
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-static gint
-gail_scale_button_get_n_actions (AtkAction *action)
-{
- return 2;
-}
-
-static const gchar*
-gail_scale_button_get_description (AtkAction *action,
- gint i)
-{
- return NULL;
-}
-
-static const gchar*
-gail_scale_button_action_get_name (AtkAction *action,
- gint i)
-{
- switch (i) {
- case 0:
- return "popup";
- case 1:
- return "popdown";
- default:
- return NULL;
- }
-}
-
-static const gchar*
-gail_scale_button_get_keybinding (AtkAction *action,
- gint i)
-{
- return NULL;
-}
-
-static gboolean
-gail_scale_button_set_description (AtkAction *action,
- gint i,
- const gchar *desc)
-{
- return FALSE;
-}
-
-
-static void
-atk_value_interface_init (AtkValueIface *iface)
-{
- iface->get_current_value = gail_scale_button_get_current_value;
- iface->get_maximum_value = gail_scale_button_get_maximum_value;
- iface->get_minimum_value = gail_scale_button_get_minimum_value;
- iface->get_minimum_increment = gail_scale_button_get_minimum_increment;
- iface->set_current_value = gail_scale_button_set_current_value;
-}
-
-static void
-gail_scale_button_get_current_value (AtkValue *obj,
- GValue *value)
-{
- GailScaleButton *scale_button;
-
- g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
-
- scale_button = GAIL_SCALE_BUTTON (obj);
- if (scale_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_current_value (ATK_VALUE (scale_button->adjustment), value);
-}
-
-static void
-gail_scale_button_get_maximum_value (AtkValue *obj,
- GValue *value)
-{
- GailScaleButton *scale_button;
-
- g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
-
- scale_button = GAIL_SCALE_BUTTON (obj);
- if (scale_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_maximum_value (ATK_VALUE (scale_button->adjustment), value);
-}
-
-static void
-gail_scale_button_get_minimum_value (AtkValue *obj,
- GValue *value)
-{
- GailScaleButton *scale_button;
-
- g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
-
- scale_button = GAIL_SCALE_BUTTON (obj);
- if (scale_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_minimum_value (ATK_VALUE (scale_button->adjustment), value);
-}
-
-static void
-gail_scale_button_get_minimum_increment (AtkValue *obj,
- GValue *value)
-{
- GailScaleButton *scale_button;
-
- g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
-
- scale_button = GAIL_SCALE_BUTTON (obj);
- if (scale_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_minimum_increment (ATK_VALUE (scale_button->adjustment), value);
-}
-
-static gboolean
-gail_scale_button_set_current_value (AtkValue *obj,
- const GValue *value)
-{
- GailScaleButton *scale_button;
-
- g_return_val_if_fail (GAIL_IS_SCALE_BUTTON (obj), FALSE);
-
- scale_button = GAIL_SCALE_BUTTON (obj);
- if (scale_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return FALSE;
-
- return atk_value_set_current_value (ATK_VALUE (scale_button->adjustment), value);
-}
-
-static void
-gail_scale_button_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkScaleButton *gtk_scale_button;
- GailScaleButton *scale_button;
-
- g_return_if_fail (GTK_IS_SCALE_BUTTON (obj));
-
- gtk_scale_button = GTK_SCALE_BUTTON (obj);
- scale_button = GAIL_SCALE_BUTTON (gtk_widget_get_accessible (GTK_WIDGET (gtk_scale_button)));
-
- if (strcmp (pspec->name, "adjustment") == 0)
- {
- /*
- * Get rid of the GailAdjustment for the GtkAdjustment
- * which was associated with the scale_button.
- */
- GtkAdjustment* gtk_adjustment;
-
- if (scale_button->adjustment)
- {
- g_object_unref (scale_button->adjustment);
- scale_button->adjustment = NULL;
- }
- /*
- * Create the GailAdjustment when notify for "adjustment" property
- * is received
- */
- gtk_adjustment = gtk_scale_button_get_adjustment (gtk_scale_button);
- scale_button->adjustment = gail_adjustment_new (gtk_adjustment);
- g_signal_connect (gtk_adjustment,
- "value-changed",
- G_CALLBACK (gail_scale_button_value_changed),
- scale_button);
- }
- else
- {
- GAIL_WIDGET_CLASS (gail_scale_button_parent_class)->notify_gtk (obj, pspec);
- }
-}
-
-static void
-gail_scale_button_value_changed (GtkAdjustment *adjustment,
- gpointer data)
-{
- GailScaleButton *scale_button;
-
- gail_return_if_fail (adjustment != NULL);
- gail_return_if_fail (data != NULL);
-
- scale_button = GAIL_SCALE_BUTTON (data);
-
- g_object_notify (G_OBJECT (scale_button), "accessible-value");
-}
-
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2008 Jan Arne Petersen <jap@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_SCALE_BUTTON_H__
-#define __GAIL_SCALE_BUTTON_H__
-
-#include <gtk/gtk.h>
-#include "gailbutton.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_SCALE_BUTTON (gail_scale_button_get_type ())
-#define GAIL_SCALE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SCALE_BUTTON, GailScaleButton))
-#define GAIL_SCALE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SCALE_BUTTON, GailScaleButtonClass))
-#define GAIL_IS_SCALE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SCALE_BUTTON))
-#define GAIL_IS_SCALE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SCALE_BUTTON))
-#define GAIL_SCALE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SCALE_BUTTON, GailScaleButtonClass))
-
-typedef struct _GailScaleButton GailScaleButton;
-typedef struct _GailScaleButtonClass GailScaleButtonClass;
-
-struct _GailScaleButton
-{
- GailButton parent;
-
- AtkObject *adjustment;
-};
-
-struct _GailScaleButtonClass
-{
- GailButtonClass parent_class;
-};
-
-GType gail_scale_button_get_type (void);
-
-G_END_DECLS
-
-#endif /* __GAIL_SCALE_BUTTON_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailscrollbar.h"
-
-static void gail_scrollbar_class_init (GailScrollbarClass *klass);
-static void gail_scrollbar_init (GailScrollbar *accessible);
-static void gail_scrollbar_initialize (AtkObject *accessible,
- gpointer data);
-
-static gint gail_scrollbar_get_index_in_parent (AtkObject *accessible);
-
-G_DEFINE_TYPE (GailScrollbar, gail_scrollbar, GAIL_TYPE_RANGE)
-
-static void
-gail_scrollbar_class_init (GailScrollbarClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->initialize = gail_scrollbar_initialize;
- class->get_index_in_parent = gail_scrollbar_get_index_in_parent;
-}
-
-static void
-gail_scrollbar_init (GailScrollbar *accessible)
-{
-}
-
-static void
-gail_scrollbar_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_scrollbar_parent_class)->initialize (accessible, data);
-
- accessible->role = ATK_ROLE_SCROLL_BAR;
-}
-
-static gint
-gail_scrollbar_get_index_in_parent (AtkObject *accessible)
-{
- GtkWidget *widget;
- GtkWidget *parent;
- GtkWidget *child;
- GtkScrolledWindow *scrolled_window;
- gint id;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- {
- /*
- * State is defunct
- */
- return -1;
- }
- g_return_val_if_fail (GTK_IS_SCROLLBAR (widget), -1);
-
- parent = gtk_widget_get_parent (widget);
- if (!GTK_IS_SCROLLED_WINDOW (parent))
- return ATK_OBJECT_CLASS (gail_scrollbar_parent_class)->get_index_in_parent (accessible);
-
- scrolled_window = GTK_SCROLLED_WINDOW (parent);
- id = 0;
- child = gtk_bin_get_child (GTK_BIN (scrolled_window));
- if (child)
- {
- if (widget == child)
- return id;
- id++;
- }
-
- child = gtk_scrolled_window_get_hscrollbar (scrolled_window);
- if (child)
- {
- if (widget == child)
- return id;
- id++;
- }
- child = gtk_scrolled_window_get_vscrollbar (scrolled_window);
- if (child)
- {
- if (widget == child)
- return id;
- }
-
- return -1;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_SCROLLBAR_H__
-#define __GAIL_SCROLLBAR_H__
-
-#include "gailrange.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_SCROLLBAR (gail_scrollbar_get_type ())
-#define GAIL_SCROLLBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SCROLLBAR, GailScrollbar))
-#define GAIL_SCROLLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SCROLLBAR, GailScrollbarClass))
-#define GAIL_IS_SCROLLBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SCROLLBAR))
-#define GAIL_IS_SCROLLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SCROLLBAR))
-#define GAIL_SCROLLBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SCROLLBAR, GailScrollbarClass))
-
-typedef struct _GailScrollbar GailScrollbar;
-typedef struct _GailScrollbarClass GailScrollbarClass;
-
-struct _GailScrollbar
-{
- GailRange parent;
-};
-
-GType gail_scrollbar_get_type (void);
-
-struct _GailScrollbarClass
-{
- GailRangeClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_SCROLLBAR_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailscrolledwindow.h"
-
-
-static void gail_scrolled_window_class_init (GailScrolledWindowClass *klass);
-static void gail_scrolled_window_init (GailScrolledWindow *window);
-static void gail_scrolled_window_real_initialize
- (AtkObject *obj,
- gpointer data);
-
-static gint gail_scrolled_window_get_n_children (AtkObject *object);
-static AtkObject* gail_scrolled_window_ref_child (AtkObject *obj,
- gint child);
-static void gail_scrolled_window_scrollbar_visibility_changed
- (GObject *object,
- GParamSpec *pspec,
- gpointer user_data);
-
-G_DEFINE_TYPE (GailScrolledWindow, gail_scrolled_window, GAIL_TYPE_CONTAINER)
-
-static void
-gail_scrolled_window_class_init (GailScrolledWindowClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->get_n_children = gail_scrolled_window_get_n_children;
- class->ref_child = gail_scrolled_window_ref_child;
- class->initialize = gail_scrolled_window_real_initialize;
-}
-
-static void
-gail_scrolled_window_init (GailScrolledWindow *window)
-{
-}
-
-static void
-gail_scrolled_window_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkScrolledWindow *window;
-
- ATK_OBJECT_CLASS (gail_scrolled_window_parent_class)->initialize (obj, data);
-
- window = GTK_SCROLLED_WINDOW (data);
-
- g_signal_connect_data (gtk_scrolled_window_get_hscrollbar (window), "notify::visible",
- G_CALLBACK (gail_scrolled_window_scrollbar_visibility_changed),
- obj, NULL, FALSE);
- g_signal_connect_data (gtk_scrolled_window_get_vscrollbar (window), "notify::visible",
- G_CALLBACK (gail_scrolled_window_scrollbar_visibility_changed),
- obj, NULL, FALSE);
-
- obj->role = ATK_ROLE_SCROLL_PANE;
-}
-
-static gint
-gail_scrolled_window_get_n_children (AtkObject *object)
-{
- GtkWidget *widget;
- GtkScrolledWindow *gtk_window;
- GList *children;
- gint n_children;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (object));
- if (widget == NULL)
- /* Object is defunct */
- return 0;
-
- gtk_window = GTK_SCROLLED_WINDOW (widget);
-
- /* Get the number of children returned by the backing GtkScrolledWindow */
-
- children = gtk_container_get_children (GTK_CONTAINER(gtk_window));
- n_children = g_list_length (children);
- g_list_free (children);
-
- /* Add one to the count for each visible scrollbar */
-
- if (gtk_scrolled_window_get_hscrollbar (gtk_window))
- n_children++;
- if (gtk_scrolled_window_get_vscrollbar (gtk_window))
- n_children++;
- return n_children;
-}
-
-static AtkObject *
-gail_scrolled_window_ref_child (AtkObject *obj,
- gint child)
-{
- GtkWidget *widget;
- GtkScrolledWindow *gtk_window;
- GtkWidget *hscrollbar, *vscrollbar;
- GList *children, *tmp_list;
- gint n_children;
- AtkObject *accessible = NULL;
-
- g_return_val_if_fail (child >= 0, NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /* Object is defunct */
- return NULL;
-
- gtk_window = GTK_SCROLLED_WINDOW (widget);
- hscrollbar = gtk_scrolled_window_get_hscrollbar (gtk_window);
- vscrollbar = gtk_scrolled_window_get_vscrollbar (gtk_window);
-
- children = gtk_container_get_children (GTK_CONTAINER (gtk_window));
- n_children = g_list_length (children);
-
- if (child == n_children)
- {
- if (gtk_scrolled_window_get_hscrollbar (gtk_window))
- accessible = gtk_widget_get_accessible (hscrollbar);
- else if (gtk_scrolled_window_get_vscrollbar (gtk_window))
- accessible = gtk_widget_get_accessible (vscrollbar);
- }
- else if (child == n_children+1 &&
- gtk_scrolled_window_get_hscrollbar (gtk_window) &&
- gtk_scrolled_window_get_vscrollbar (gtk_window))
- accessible = gtk_widget_get_accessible (vscrollbar);
- else if (child < n_children)
- {
- tmp_list = g_list_nth (children, child);
- if (tmp_list)
- accessible = gtk_widget_get_accessible (
- GTK_WIDGET (tmp_list->data));
- }
-
- g_list_free (children);
- if (accessible)
- g_object_ref (accessible);
- return accessible;
-}
-
-static void
-gail_scrolled_window_scrollbar_visibility_changed (GObject *object,
- GParamSpec *pspec,
- gpointer user_data)
-{
- if (!strcmp (pspec->name, "visible"))
- {
- gint index;
- gint n_children;
- gboolean child_added = FALSE;
- GList *children;
- AtkObject *child;
- GtkScrolledWindow *gtk_window;
- GtkWidget *hscrollbar, *vscrollbar;
- GailScrolledWindow *gail_window = GAIL_SCROLLED_WINDOW (user_data);
- gchar *signal_name;
-
- gtk_window = GTK_SCROLLED_WINDOW (gtk_accessible_get_widget (GTK_ACCESSIBLE (user_data)));
- if (gtk_window == NULL)
- return;
- children = gtk_container_get_children (GTK_CONTAINER (gtk_window));
- index = n_children = g_list_length (children);
- g_list_free (children);
-
- hscrollbar = gtk_scrolled_window_get_hscrollbar (gtk_window);
- vscrollbar = gtk_scrolled_window_get_vscrollbar (gtk_window);
-
- if ((gpointer) object == (gpointer) (hscrollbar))
- {
- if (gtk_scrolled_window_get_hscrollbar (gtk_window))
- child_added = TRUE;
-
- child = gtk_widget_get_accessible (hscrollbar);
- }
- else if ((gpointer) object == (gpointer) (vscrollbar))
- {
- if (gtk_scrolled_window_get_vscrollbar (gtk_window))
- child_added = TRUE;
-
- child = gtk_widget_get_accessible (vscrollbar);
- if (gtk_scrolled_window_get_hscrollbar (gtk_window))
- index = n_children+1;
- }
- else
- {
- g_assert_not_reached ();
- return;
- }
-
- if (child_added)
- signal_name = "children_changed::add";
- else
- signal_name = "children_changed::delete";
-
- g_signal_emit_by_name (gail_window, signal_name, index, child, NULL);
- }
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_SCROLLED_WINDOW_H__
-#define __GAIL_SCROLLED_WINDOW_H__
-
-#include "gailcontainer.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_SCROLLED_WINDOW (gail_scrolled_window_get_type ())
-#define GAIL_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SCROLLED_WINDOW, GailScrolledWindow))
-#define GAIL_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SCROLLED_WINDOW, GailScrolledWindowClass))
-#define GAIL_IS_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SCROLLED_WINDOW))
-#define GAIL_IS_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SCROLLED_WINDOW))
-#define GAIL_SCROLLED_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SCROLLED_WINDOW, GailScrolledWindowClass))
-
-typedef struct _GailScrolledWindow GailScrolledWindow;
-typedef struct _GailScrolledWindowClass GailScrolledWindowClass;
-
-struct _GailScrolledWindow
-{
- GailContainer parent;
-};
-
-GType gail_scrolled_window_get_type (void);
-
-struct _GailScrolledWindowClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_SCROLLED_WINDOW_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailseparator.h"
-
-static void gail_separator_class_init (GailSeparatorClass *klass);
-static void gail_separator_init (GailSeparator *accessible);
-static void gail_separator_initialize (AtkObject *accessible,
- gpointer data);
-
-G_DEFINE_TYPE (GailSeparator, gail_separator, GAIL_TYPE_WIDGET)
-
-static void
-gail_separator_class_init (GailSeparatorClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->initialize = gail_separator_initialize;
-}
-
-static void
-gail_separator_init (GailSeparator *accessible)
-{
-}
-
-static void
-gail_separator_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_separator_parent_class)->initialize (accessible, data);
-
- accessible->role = ATK_ROLE_SEPARATOR;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_SEPARATOR_H__
-#define __GAIL_SEPARATOR_H__
-
-#include "gailwidget.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_SEPARATOR (gail_separator_get_type ())
-#define GAIL_SEPARATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SEPARATOR, GailSeparator))
-#define GAIL_SEPARATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SEPARATOR, GailSeparatorClass))
-#define GAIL_IS_SEPARATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SEPARATOR))
-#define GAIL_IS_SEPARATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SEPARATOR))
-#define GAIL_SEPARATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SEPARATOR, GailSeparatorClass))
-
-typedef struct _GailSeparator GailSeparator;
-typedef struct _GailSeparatorClass GailSeparatorClass;
-
-struct _GailSeparator
-{
- GailWidget parent;
-};
-
-GType gail_separator_get_type (void);
-
-struct _GailSeparatorClass
-{
- GailWidgetClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_SEPARATOR_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailspinbutton.h"
-#include "gailadjustment.h"
-#include "gail-private-macros.h"
-
-static void gail_spin_button_class_init (GailSpinButtonClass *klass);
-static void gail_spin_button_init (GailSpinButton *button);
-static void gail_spin_button_real_initialize (AtkObject *obj,
- gpointer data);
-static void gail_spin_button_finalize (GObject *object);
-
-static void atk_value_interface_init (AtkValueIface *iface);
-
-static void gail_spin_button_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-
-static void gail_spin_button_get_current_value (AtkValue *obj,
- GValue *value);
-static void gail_spin_button_get_maximum_value (AtkValue *obj,
- GValue *value);
-static void gail_spin_button_get_minimum_value (AtkValue *obj,
- GValue *value);
-static void gail_spin_button_get_minimum_increment (AtkValue *obj,
- GValue *value);
-static gboolean gail_spin_button_set_current_value (AtkValue *obj,
- const GValue *value);
-static void gail_spin_button_value_changed (GtkAdjustment *adjustment,
- gpointer data);
-
-G_DEFINE_TYPE_WITH_CODE (GailSpinButton, gail_spin_button, GAIL_TYPE_ENTRY,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
-
-static void
-gail_spin_button_class_init (GailSpinButtonClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailWidgetClass *widget_class;
-
- widget_class = (GailWidgetClass*)klass;
-
- widget_class->notify_gtk = gail_spin_button_real_notify_gtk;
-
- class->initialize = gail_spin_button_real_initialize;
-
- gobject_class->finalize = gail_spin_button_finalize;
-}
-
-static void
-gail_spin_button_init (GailSpinButton *button)
-{
-}
-
-static void
-gail_spin_button_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkAdjustment *adjustment;
- GailSpinButton *spin_button = GAIL_SPIN_BUTTON (obj);
- GtkSpinButton *gtk_spin_button;
-
- ATK_OBJECT_CLASS (gail_spin_button_parent_class)->initialize (obj, data);
-
- gtk_spin_button = GTK_SPIN_BUTTON (data);
- /*
- * If a GtkAdjustment already exists for the spin_button,
- * create the GailAdjustment
- */
- adjustment = gtk_spin_button_get_adjustment (gtk_spin_button);
- if (adjustment)
- {
- spin_button->adjustment = gail_adjustment_new (adjustment);
- g_signal_connect (adjustment,
- "value-changed",
- G_CALLBACK (gail_spin_button_value_changed),
- obj);
- }
- else
- spin_button->adjustment = NULL;
-
- obj->role = ATK_ROLE_SPIN_BUTTON;
-
-}
-
-static void
-atk_value_interface_init (AtkValueIface *iface)
-{
- iface->get_current_value = gail_spin_button_get_current_value;
- iface->get_maximum_value = gail_spin_button_get_maximum_value;
- iface->get_minimum_value = gail_spin_button_get_minimum_value;
- iface->get_minimum_increment = gail_spin_button_get_minimum_increment;
- iface->set_current_value = gail_spin_button_set_current_value;
-}
-
-static void
-gail_spin_button_get_current_value (AtkValue *obj,
- GValue *value)
-{
- GailSpinButton *spin_button;
-
- g_return_if_fail (GAIL_IS_SPIN_BUTTON (obj));
-
- spin_button = GAIL_SPIN_BUTTON (obj);
- if (spin_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_current_value (ATK_VALUE (spin_button->adjustment), value);
-}
-
-static void
-gail_spin_button_get_maximum_value (AtkValue *obj,
- GValue *value)
-{
- GailSpinButton *spin_button;
-
- g_return_if_fail (GAIL_IS_SPIN_BUTTON (obj));
-
- spin_button = GAIL_SPIN_BUTTON (obj);
- if (spin_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_maximum_value (ATK_VALUE (spin_button->adjustment), value);
-}
-
-static void
-gail_spin_button_get_minimum_value (AtkValue *obj,
- GValue *value)
-{
- GailSpinButton *spin_button;
-
- g_return_if_fail (GAIL_IS_SPIN_BUTTON (obj));
-
- spin_button = GAIL_SPIN_BUTTON (obj);
- if (spin_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_minimum_value (ATK_VALUE (spin_button->adjustment), value);
-}
-
-static void
-gail_spin_button_get_minimum_increment (AtkValue *obj, GValue *value)
-{
- GailSpinButton *spin_button;
-
- g_return_if_fail (GAIL_IS_SPIN_BUTTON (obj));
-
- spin_button = GAIL_SPIN_BUTTON (obj);
- if (spin_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return;
-
- atk_value_get_minimum_increment (ATK_VALUE (spin_button->adjustment), value);
-}
-
-static gboolean
-gail_spin_button_set_current_value (AtkValue *obj,
- const GValue *value)
-{
- GailSpinButton *spin_button;
-
- g_return_val_if_fail (GAIL_IS_SPIN_BUTTON (obj), FALSE);
-
- spin_button = GAIL_SPIN_BUTTON (obj);
- if (spin_button->adjustment == NULL)
- /*
- * Adjustment has not been specified
- */
- return FALSE;
-
- return atk_value_set_current_value (ATK_VALUE (spin_button->adjustment), value);
-}
-
-static void
-gail_spin_button_finalize (GObject *object)
-{
- GailSpinButton *spin_button = GAIL_SPIN_BUTTON (object);
-
- if (spin_button->adjustment)
- {
- g_object_unref (spin_button->adjustment);
- spin_button->adjustment = NULL;
- }
- G_OBJECT_CLASS (gail_spin_button_parent_class)->finalize (object);
-}
-
-
-static void
-gail_spin_button_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkWidget *widget = GTK_WIDGET (obj);
- GailSpinButton *spin_button = GAIL_SPIN_BUTTON (gtk_widget_get_accessible (widget));
-
- if (strcmp (pspec->name, "adjustment") == 0)
- {
- /*
- * Get rid of the GailAdjustment for the GtkAdjustment
- * which was associated with the spin_button.
- */
- GtkAdjustment* adjustment;
- GtkSpinButton* gtk_spin_button;
-
- if (spin_button->adjustment)
- {
- g_object_unref (spin_button->adjustment);
- spin_button->adjustment = NULL;
- }
- /*
- * Create the GailAdjustment when notify for "adjustment" property
- * is received
- */
- gtk_spin_button = GTK_SPIN_BUTTON (widget);
- adjustment = gtk_spin_button_get_adjustment (gtk_spin_button);
- spin_button->adjustment = gail_adjustment_new (adjustment);
- g_signal_connect (adjustment,
- "value-changed",
- G_CALLBACK (gail_spin_button_value_changed),
- spin_button);
- }
- else
- GAIL_WIDGET_CLASS (gail_spin_button_parent_class)->notify_gtk (obj, pspec);
-}
-
-
-static void
-gail_spin_button_value_changed (GtkAdjustment *adjustment,
- gpointer data)
-{
- GailSpinButton *spin_button;
-
- gail_return_if_fail (adjustment != NULL);
- gail_return_if_fail (data != NULL);
-
- spin_button = GAIL_SPIN_BUTTON (data);
-
- g_object_notify (G_OBJECT (spin_button), "accessible-value");
-}
-
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_SPIN_BUTTON_H__
-#define __GAIL_SPIN_BUTTON_H__
-
-#include "gailentry.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_SPIN_BUTTON (gail_spin_button_get_type ())
-#define GAIL_SPIN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SPIN_BUTTON, GailSpinButton))
-#define GAIL_SPIN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SPIN_BUTTON, GailSpinButtonClass))
-#define GAIL_IS_SPIN_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SPIN_BUTTON))
-#define GAIL_IS_SPIN_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SPIN_BUTTON))
-#define GAIL_SPIN_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SPIN_BUTTON, GailSpinButtonClass))
-
-typedef struct _GailSpinButton GailSpinButton;
-typedef struct _GailSpinButtonClass GailSpinButtonClass;
-
-struct _GailSpinButton
-{
- GailEntry parent;
-
- AtkObject *adjustment;
-};
-
-GType gail_spin_button_get_type (void);
-
-struct _GailSpinButtonClass
-{
- GailEntryClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_SPIN_BUTTON_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailstatusbar.h"
-#include <libgail-util/gailmisc.h>
-
-static void gail_statusbar_class_init (GailStatusbarClass *klass);
-static void gail_statusbar_init (GailStatusbar *bar);
-static const gchar* gail_statusbar_get_name (AtkObject *obj);
-static gint gail_statusbar_get_n_children (AtkObject *obj);
-static AtkObject* gail_statusbar_ref_child (AtkObject *obj,
- gint i);
-static void gail_statusbar_real_initialize (AtkObject *obj,
- gpointer data);
-
-static gint gail_statusbar_notify (GObject *obj,
- GParamSpec *pspec,
- gpointer user_data);
-static void gail_statusbar_finalize (GObject *object);
-static void gail_statusbar_init_textutil (GailStatusbar *statusbar,
- GtkWidget *label);
-
-/* atktext.h */
-static void atk_text_interface_init (AtkTextIface *iface);
-
-static gchar* gail_statusbar_get_text (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gunichar gail_statusbar_get_character_at_offset
- (AtkText *text,
- gint offset);
-static gchar* gail_statusbar_get_text_before_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_statusbar_get_text_at_offset(AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_statusbar_get_text_after_offset
- (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gint gail_statusbar_get_character_count (AtkText *text);
-static void gail_statusbar_get_character_extents
- (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static gint gail_statusbar_get_offset_at_point(AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static AtkAttributeSet* gail_statusbar_get_run_attributes
- (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet* gail_statusbar_get_default_attributes
- (AtkText *text);
-static GtkWidget* get_label_from_statusbar (GtkWidget *statusbar);
-
-G_DEFINE_TYPE_WITH_CODE (GailStatusbar, gail_statusbar, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
-
-static void
-gail_statusbar_class_init (GailStatusbarClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailContainerClass *container_class;
-
- container_class = (GailContainerClass*)klass;
-
- gobject_class->finalize = gail_statusbar_finalize;
-
- class->get_name = gail_statusbar_get_name;
- class->get_n_children = gail_statusbar_get_n_children;
- class->ref_child = gail_statusbar_ref_child;
- class->initialize = gail_statusbar_real_initialize;
- /*
- * As we report the statusbar as having no children we are not interested
- * in add and remove signals
- */
- container_class->add_gtk = NULL;
- container_class->remove_gtk = NULL;
-}
-
-static void
-gail_statusbar_init (GailStatusbar *bar)
-{
-}
-
-static const gchar*
-gail_statusbar_get_name (AtkObject *obj)
-{
- const gchar* name;
-
- g_return_val_if_fail (GAIL_IS_STATUSBAR (obj), NULL);
-
- name = ATK_OBJECT_CLASS (gail_statusbar_parent_class)->get_name (obj);
- if (name != NULL)
- return name;
- else
- {
- /*
- * Get the text on the label
- */
- GtkWidget *widget;
- GtkWidget *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- g_return_val_if_fail (GTK_IS_STATUSBAR (widget), NULL);
- label = get_label_from_statusbar (widget);
- if (GTK_IS_LABEL (label))
- return gtk_label_get_label (GTK_LABEL (label));
- else
- return NULL;
- }
-}
-
-static gint
-gail_statusbar_get_n_children (AtkObject *obj)
-{
- GtkWidget *widget;
- GList *children;
- gint count = 0;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return 0;
-
- children = gtk_container_get_children (GTK_CONTAINER (widget));
- if (children != NULL)
- {
- count = g_list_length (children);
- g_list_free (children);
- }
-
- return count;
-}
-
-static AtkObject*
-gail_statusbar_ref_child (AtkObject *obj,
- gint i)
-{
- GList *children, *tmp_list;
- AtkObject *accessible;
- GtkWidget *widget;
-
- g_return_val_if_fail ((i >= 0), NULL);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- return NULL;
-
- children = gtk_container_get_children (GTK_CONTAINER (widget));
- if (children == NULL)
- return NULL;
-
- tmp_list = g_list_nth (children, i);
- if (!tmp_list)
- {
- g_list_free (children);
- return NULL;
- }
- accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
-
- g_list_free (children);
- g_object_ref (accessible);
- return accessible;
-}
-
-static void
-gail_statusbar_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GailStatusbar *statusbar = GAIL_STATUSBAR (obj);
- GtkWidget *label;
-
- ATK_OBJECT_CLASS (gail_statusbar_parent_class)->initialize (obj, data);
-
- /*
- * We get notified of changes to the label
- */
- label = get_label_from_statusbar (GTK_WIDGET (data));
- if (GTK_IS_LABEL (label))
- {
- gail_statusbar_init_textutil (statusbar, label);
- }
-
- obj->role = ATK_ROLE_STATUSBAR;
-
-}
-
-static gint
-gail_statusbar_notify (GObject *obj,
- GParamSpec *pspec,
- gpointer user_data)
-{
- AtkObject *atk_obj = ATK_OBJECT (user_data);
- GtkLabel *label;
- GailStatusbar *statusbar;
-
- if (strcmp (pspec->name, "label") == 0)
- {
- const gchar* label_text;
-
- label = GTK_LABEL (obj);
-
- label_text = gtk_label_get_text (label);
-
- statusbar = GAIL_STATUSBAR (atk_obj);
- gail_text_util_text_setup (statusbar->textutil, label_text);
-
- if (atk_obj->name == NULL)
- {
- /*
- * The label has changed so notify a change in accessible-name
- */
- g_object_notify (G_OBJECT (atk_obj), "accessible-name");
- }
- /*
- * The label is the only property which can be changed
- */
- g_signal_emit_by_name (atk_obj, "visible_data_changed");
- }
- return 1;
-}
-
-static void
-gail_statusbar_init_textutil (GailStatusbar *statusbar,
- GtkWidget *label)
-{
- const gchar *label_text;
-
- statusbar->textutil = gail_text_util_new ();
- label_text = gtk_label_get_text (GTK_LABEL (label));
- gail_text_util_text_setup (statusbar->textutil, label_text);
- g_signal_connect (label,
- "notify",
- (GCallback) gail_statusbar_notify,
- statusbar);
-}
-
-static void
-gail_statusbar_finalize (GObject *object)
-{
- GailStatusbar *statusbar = GAIL_STATUSBAR (object);
-
- if (statusbar->textutil)
- {
- g_object_unref (statusbar->textutil);
- }
- G_OBJECT_CLASS (gail_statusbar_parent_class)->finalize (object);
-}
-
-/* atktext.h */
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_statusbar_get_text;
- iface->get_character_at_offset = gail_statusbar_get_character_at_offset;
- iface->get_text_before_offset = gail_statusbar_get_text_before_offset;
- iface->get_text_at_offset = gail_statusbar_get_text_at_offset;
- iface->get_text_after_offset = gail_statusbar_get_text_after_offset;
- iface->get_character_count = gail_statusbar_get_character_count;
- iface->get_character_extents = gail_statusbar_get_character_extents;
- iface->get_offset_at_point = gail_statusbar_get_offset_at_point;
- iface->get_run_attributes = gail_statusbar_get_run_attributes;
- iface->get_default_attributes = gail_statusbar_get_default_attributes;
-}
-
-static gchar*
-gail_statusbar_get_text (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailStatusbar *statusbar;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL (label))
- return NULL;
-
- statusbar = GAIL_STATUSBAR (text);
- if (!statusbar->textutil)
- gail_statusbar_init_textutil (statusbar, label);
-
- label_text = gtk_label_get_text (GTK_LABEL (label));
-
- if (label_text == NULL)
- return NULL;
- else
- {
- return gail_text_util_get_substring (statusbar->textutil,
- start_pos, end_pos);
- }
-}
-
-static gchar*
-gail_statusbar_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailStatusbar *statusbar;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get label */
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- statusbar = GAIL_STATUSBAR (text);
- if (!statusbar->textutil)
- gail_statusbar_init_textutil (statusbar, label);
-
- return gail_text_util_get_text (statusbar->textutil,
- gtk_label_get_layout (GTK_LABEL (label)), GAIL_BEFORE_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_statusbar_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailStatusbar *statusbar;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Get label */
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- statusbar = GAIL_STATUSBAR (text);
- if (!statusbar->textutil)
- gail_statusbar_init_textutil (statusbar, label);
-
- return gail_text_util_get_text (statusbar->textutil,
- gtk_label_get_layout (GTK_LABEL (label)), GAIL_AT_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_statusbar_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- GailStatusbar *statusbar;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- {
- /* State is defunct */
- return NULL;
- }
-
- /* Get label */
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- statusbar = GAIL_STATUSBAR (text);
- if (!statusbar->textutil)
- gail_statusbar_init_textutil (statusbar, label);
-
- return gail_text_util_get_text (statusbar->textutil,
- gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET,
- boundary_type, offset, start_offset, end_offset);
-}
-
-static gint
-gail_statusbar_get_character_count (AtkText *text)
-{
- GtkWidget *widget;
- GtkWidget *label;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL(label))
- return 0;
-
- return g_utf8_strlen (gtk_label_get_text (GTK_LABEL (label)), -1);
-}
-
-static void
-gail_statusbar_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkWidget *label;
- PangoRectangle char_rect;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
-
- if (widget == NULL)
- /* State is defunct */
- return;
-
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL(label))
- return;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- index = g_utf8_offset_to_pointer (label_text, offset) - label_text;
- pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect);
-
- gail_misc_get_extents_from_pango_rectangle (label, &char_rect,
- x_layout, y_layout, x, y, width, height, coords);
-}
-
-static gint
-gail_statusbar_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- GtkWidget *widget;
- GtkWidget *label;
- gint index, x_layout, y_layout;
- const gchar *label_text;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL(label))
- return -1;
-
- gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
-
- index = gail_misc_get_index_at_point_in_layout (label,
- gtk_label_get_layout (GTK_LABEL (label)),
- x_layout, y_layout, x, y, coords);
- label_text = gtk_label_get_text (GTK_LABEL (label));
- if (index == -1)
- {
- if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
- return g_utf8_strlen (label_text, -1);
-
- return index;
- }
- else
- return g_utf8_pointer_to_offset (label_text, label_text + index);
-}
-
-static AtkAttributeSet*
-gail_statusbar_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- AtkAttributeSet *at_set = NULL;
- GtkJustification justify;
- GtkTextDirection dir;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- /* Get values set for entire label, if any */
- justify = gtk_label_get_justify (GTK_LABEL (label));
- if (justify != GTK_JUSTIFY_CENTER)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_JUSTIFICATION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify)));
- }
- dir = gtk_widget_get_direction (label);
- if (dir == GTK_TEXT_DIR_RTL)
- {
- at_set = gail_misc_add_attribute (at_set,
- ATK_TEXT_ATTR_DIRECTION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir)));
- }
-
- at_set = gail_misc_layout_get_run_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- (gchar *) gtk_label_get_text (GTK_LABEL (label)),
- offset,
- start_offset,
- end_offset);
- return at_set;
-}
-
-static AtkAttributeSet*
-gail_statusbar_get_default_attributes (AtkText *text)
-{
- GtkWidget *widget;
- GtkWidget *label;
- AtkAttributeSet *at_set = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL(label))
- return NULL;
-
- at_set = gail_misc_get_default_attributes (at_set,
- gtk_label_get_layout (GTK_LABEL (label)),
- widget);
- return at_set;
-}
-
-static gunichar
-gail_statusbar_get_character_at_offset (AtkText *text,
- gint offset)
-{
- GtkWidget *widget;
- GtkWidget *label;
- const gchar *string;
- gchar *index;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return '\0';
-
- label = get_label_from_statusbar (widget);
-
- if (!GTK_IS_LABEL(label))
- return '\0';
- string = gtk_label_get_text (GTK_LABEL (label));
- if (offset >= g_utf8_strlen (string, -1))
- return '\0';
- index = g_utf8_offset_to_pointer (string, offset);
-
- return g_utf8_get_char (index);
-}
-
-static GtkWidget*
-get_label_from_statusbar (GtkWidget *statusbar)
-{
- GtkWidget *message_area;
- GList *children, *l;
- GtkWidget *child;
-
- message_area = gtk_statusbar_get_message_area (GTK_STATUSBAR (statusbar));
-
- children = gtk_container_get_children (GTK_CONTAINER (message_area));
- for (l = children; l; l = l->next)
- {
- child = l->data;
- if (GTK_IS_LABEL (child))
- break;
- child = NULL;
- }
-
- g_list_free (children);
-
- return child;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_STATUSBAR_H__
-#define __GAIL_STATUSBAR_H__
-
-#include "gailcontainer.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_STATUSBAR (gail_statusbar_get_type ())
-#define GAIL_STATUSBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_STATUSBAR, GailStatusbar))
-#define GAIL_STATUSBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_STATUSBAR, GailStatusbarClass))
-#define GAIL_IS_STATUSBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_STATUSBAR))
-#define GAIL_IS_STATUSBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_STATUSBAR))
-#define GAIL_STATUSBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_STATUSBAR, GailStatusbarClass))
-
-typedef struct _GailStatusbar GailStatusbar;
-typedef struct _GailStatusbarClass GailStatusbarClass;
-
-struct _GailStatusbar
-{
- GailContainer parent;
-
- GailTextUtil *textutil;
-};
-
-GType gail_statusbar_get_type (void);
-
-struct _GailStatusbarClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_STATUSBAR_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <gtk/gtk.h>
-#include "gailsubmenuitem.h"
-
-static void gail_sub_menu_item_class_init (GailSubMenuItemClass *klass);
-static void gail_sub_menu_item_init (GailSubMenuItem *item);
-static void gail_sub_menu_item_real_initialize (AtkObject *obj,
- gpointer data);
-
-static void atk_selection_interface_init (AtkSelectionIface *iface);
-static gboolean gail_sub_menu_item_add_selection (AtkSelection *selection,
- gint i);
-static gboolean gail_sub_menu_item_clear_selection (AtkSelection *selection);
-static AtkObject* gail_sub_menu_item_ref_selection (AtkSelection *selection,
- gint i);
-static gint gail_sub_menu_item_get_selection_count
- (AtkSelection *selection);
-static gboolean gail_sub_menu_item_is_child_selected
- (AtkSelection *selection,
- gint i);
-static gboolean gail_sub_menu_item_remove_selection (AtkSelection *selection,
- gint i);
-static gint menu_item_add_gtk (GtkContainer *container,
- GtkWidget *widget);
-static gint menu_item_remove_gtk (GtkContainer *container,
- GtkWidget *widget);
-
-G_DEFINE_TYPE_WITH_CODE (GailSubMenuItem, gail_sub_menu_item, GAIL_TYPE_MENU_ITEM,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
-
-static void
-gail_sub_menu_item_class_init (GailSubMenuItemClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- class->initialize = gail_sub_menu_item_real_initialize;
-}
-
-static void
-gail_sub_menu_item_init (GailSubMenuItem *item)
-{
-}
-
-static void
-gail_sub_menu_item_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkWidget *submenu;
-
- ATK_OBJECT_CLASS (gail_sub_menu_item_parent_class)->initialize (obj, data);
-
- submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (data));
- g_return_if_fail (submenu);
-
- g_signal_connect (submenu,
- "add",
- G_CALLBACK (menu_item_add_gtk),
- NULL);
- g_signal_connect (submenu,
- "remove",
- G_CALLBACK (menu_item_remove_gtk),
- NULL);
-
- obj->role = ATK_ROLE_MENU;
-}
-
-AtkObject*
-gail_sub_menu_item_new (GtkWidget *widget)
-{
- GObject *object;
- AtkObject *accessible;
-
- g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), NULL);
-
- object = g_object_new (GAIL_TYPE_SUB_MENU_ITEM, NULL);
-
- accessible = ATK_OBJECT (object);
- atk_object_initialize (accessible, widget);
-
- return accessible;
-}
-
-static void
-atk_selection_interface_init (AtkSelectionIface *iface)
-{
- iface->add_selection = gail_sub_menu_item_add_selection;
- iface->clear_selection = gail_sub_menu_item_clear_selection;
- iface->ref_selection = gail_sub_menu_item_ref_selection;
- iface->get_selection_count = gail_sub_menu_item_get_selection_count;
- iface->is_child_selected = gail_sub_menu_item_is_child_selected;
- iface->remove_selection = gail_sub_menu_item_remove_selection;
- /*
- * select_all_selection does not make sense for a submenu of a menu item
- * so no implementation is provided.
- */
-}
-
-static gboolean
-gail_sub_menu_item_add_selection (AtkSelection *selection,
- gint i)
-{
- GtkMenuShell *shell;
- GList *kids;
- guint length;
- GtkWidget *widget;
- GtkWidget *submenu;
- GtkWidget *child;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
- g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
- shell = GTK_MENU_SHELL (submenu);
- kids = gtk_container_get_children (GTK_CONTAINER (shell));
- length = g_list_length (kids);
- if (i < 0 || i > length)
- {
- g_list_free (kids);
- return FALSE;
- }
-
- child = g_list_nth_data (kids, i);
- g_list_free (kids);
- g_return_val_if_fail (GTK_IS_MENU_ITEM(child), FALSE);
- gtk_menu_shell_select_item (shell, GTK_WIDGET (child));
- return TRUE;
-}
-
-static gboolean
-gail_sub_menu_item_clear_selection (AtkSelection *selection)
-{
- GtkMenuShell *shell;
- GtkWidget *widget;
- GtkWidget *submenu;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
- g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
- shell = GTK_MENU_SHELL (submenu);
-
- gtk_menu_shell_deselect (shell);
- return TRUE;
-}
-
-static AtkObject*
-gail_sub_menu_item_ref_selection (AtkSelection *selection,
- gint i)
-{
- GtkMenuShell *shell;
- AtkObject *obj;
- GtkWidget *widget;
- GtkWidget *submenu;
- GtkWidget *item;
-
- if (i != 0)
- return NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
- g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), NULL);
- shell = GTK_MENU_SHELL (submenu);
-
- item = gtk_menu_shell_get_selected_item (shell);
- if (item != NULL)
- {
- obj = gtk_widget_get_accessible (item);
- g_object_ref (obj);
- return obj;
- }
- else
- {
- return NULL;
- }
-}
-
-static gint
-gail_sub_menu_item_get_selection_count (AtkSelection *selection)
-{
- GtkMenuShell *shell;
- GtkWidget *widget;
- GtkWidget *submenu;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
- g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
- shell = GTK_MENU_SHELL (submenu);
-
- /*
- * Identifies the currently selected menu item
- */
- if (gtk_menu_shell_get_selected_item (shell) == NULL)
- return 0;
- else
- return 1;
-}
-
-static gboolean
-gail_sub_menu_item_is_child_selected (AtkSelection *selection,
- gint i)
-{
- GtkMenuShell *shell;
- gint j;
- GtkWidget *widget;
- GtkWidget *submenu;
- GtkWidget *item;
- GList *kids;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
- g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
- shell = GTK_MENU_SHELL (submenu);
-
- item = gtk_menu_shell_get_selected_item (shell);
- if (item == NULL)
- return FALSE;
-
- kids = gtk_container_get_children (GTK_CONTAINER (shell));
- j = g_list_index (kids, item);
- g_list_free (kids);
-
- return (j==i);
-}
-
-static gboolean
-gail_sub_menu_item_remove_selection (AtkSelection *selection,
- gint i)
-{
- GtkMenuShell *shell;
- GtkWidget *widget;
- GtkWidget *submenu;
- GtkWidget *item;
-
- if (i != 0)
- return FALSE;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
- g_return_val_if_fail (GTK_IS_MENU_SHELL (submenu), FALSE);
- shell = GTK_MENU_SHELL (submenu);
-
- item = gtk_menu_shell_get_selected_item (shell);
- if (item && gtk_menu_item_get_submenu (GTK_MENU_ITEM (item)))
- {
- /*
- * Menu item contains a menu and it is the selected menu item
- * so deselect it.
- */
- gtk_menu_shell_deselect (shell);
- }
- return TRUE;
-}
-
-static gint
-menu_item_add_gtk (GtkContainer *container,
- GtkWidget *widget)
-{
- GtkWidget *parent_widget;
- AtkObject *atk_parent;
- AtkObject *atk_child;
- GailContainer *gail_container;
- gint index;
-
- g_return_val_if_fail (GTK_IS_MENU (container), 1);
-
- parent_widget = gtk_menu_get_attach_widget (GTK_MENU (container));
- if (GTK_IS_MENU_ITEM (parent_widget))
- {
- atk_parent = gtk_widget_get_accessible (parent_widget);
- atk_child = gtk_widget_get_accessible (widget);
-
- gail_container = GAIL_CONTAINER (atk_parent);
- g_object_notify (G_OBJECT (atk_child), "accessible_parent");
-
- g_list_free (gail_container->children);
- gail_container->children = gtk_container_get_children (container);
- index = g_list_index (gail_container->children, widget);
- g_signal_emit_by_name (atk_parent, "children_changed::add",
- index, atk_child, NULL);
- }
- return 1;
-}
-
-static gint
-menu_item_remove_gtk (GtkContainer *container,
- GtkWidget *widget)
-{
- GtkWidget *parent_widget;
- AtkObject *atk_parent;
- AtkObject *atk_child;
- GailContainer *gail_container;
- AtkPropertyValues values = { NULL };
- gint index;
- gint list_length;
-
- g_return_val_if_fail (GTK_IS_MENU (container), 1);
-
- parent_widget = gtk_menu_get_attach_widget (GTK_MENU (container));
- if (GTK_IS_MENU_ITEM (parent_widget))
- {
- atk_parent = gtk_widget_get_accessible (parent_widget);
- atk_child = gtk_widget_get_accessible (widget);
-
- gail_container = GAIL_CONTAINER (atk_parent);
- g_value_init (&values.old_value, G_TYPE_POINTER);
- g_value_set_pointer (&values.old_value, atk_parent);
- values.property_name = "accessible-parent";
- g_signal_emit_by_name (atk_child,
- "property_change::accessible-parent", &values, NULL);
-
- index = g_list_index (gail_container->children, widget);
- list_length = g_list_length (gail_container->children);
- g_list_free (gail_container->children);
- gail_container->children = gtk_container_get_children (container);
- if (index >= 0 && index <= list_length)
- g_signal_emit_by_name (atk_parent, "children_changed::remove",
- index, atk_child, NULL);
- }
- return 1;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2002 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_SUB_MENU_ITEM_H__
-#define __GAIL_SUB_MENU_ITEM_H__
-
-#include "gailmenuitem.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_SUB_MENU_ITEM (gail_sub_menu_item_get_type ())
-#define GAIL_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SUB_MENU_ITEM, GailSubMenuItem))
-#define GAIL_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SUB_MENU_ITEM, GailSubMenuItemClass))
-#define GAIL_IS_SUB_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SUB_MENU_ITEM))
-#define GAIL_IS_SUB_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SUB_MENU_ITEM))
-#define GAIL_SUB_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SUB_MENU_ITEM, GailSubMenuItemClass))
-
-typedef struct _GailSubMenuItem GailSubMenuItem;
-typedef struct _GailSubMenuItemClass GailSubMenuItemClass;
-
-struct _GailSubMenuItem
-{
- GailMenuItem parent;
-
-};
-
-GType gail_sub_menu_item_get_type (void);
-
-struct _GailSubMenuItemClass
-{
- GailMenuItemClass parent_class;
-};
-
-AtkObject* gail_sub_menu_item_new (GtkWidget *widget);
-
-G_END_DECLS
-
-#endif /* __GAIL_SUB_MENU_ITEM_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailtextcell.h"
-#include "gailcontainercell.h"
-#include "gailcellparent.h"
-#include <libgail-util/gailmisc.h>
-#include "gail-private-macros.h"
-
-static void gail_text_cell_class_init (GailTextCellClass *klass);
-static void gail_text_cell_init (GailTextCell *text_cell);
-static void gail_text_cell_finalize (GObject *object);
-
-static const gchar* gail_text_cell_get_name (AtkObject *atk_obj);
-
-static void atk_text_interface_init (AtkTextIface *iface);
-
-/* atktext.h */
-
-static gchar* gail_text_cell_get_text (AtkText *text,
- gint start_pos,
- gint end_pos);
-static gunichar gail_text_cell_get_character_at_offset (AtkText *text,
- gint offset);
-static gchar* gail_text_cell_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_text_cell_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_text_cell_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gint gail_text_cell_get_character_count (AtkText *text);
-static gint gail_text_cell_get_caret_offset (AtkText *text);
-static gboolean gail_text_cell_set_caret_offset (AtkText *text,
- gint offset);
-static void gail_text_cell_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static gint gail_text_cell_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static AtkAttributeSet* gail_text_cell_get_run_attributes
- (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet* gail_text_cell_get_default_attributes
- (AtkText *text);
-
-static PangoLayout* create_pango_layout (GtkCellRendererText *gtk_renderer,
- GtkWidget *widget);
-static void add_attr (PangoAttrList *attr_list,
- PangoAttribute *attr);
-
-/* Misc */
-
-static gboolean gail_text_cell_update_cache (GailRendererCell *cell,
- gboolean emit_change_signal);
-
-gchar *gail_text_cell_property_list[] = {
- /* Set font_desc first since it resets other values if it is NULL */
- "font_desc",
-
- "attributes",
- "background-gdk",
- "editable",
- "family",
- "foreground-gdk",
- "rise",
- "scale",
- "size",
- "size-points",
- "stretch",
- "strikethrough",
- "style",
- "text",
- "underline",
- "variant",
- "weight",
-
- /* Also need the sets */
- "background-set",
- "editable-set",
- "family-set",
- "foreground-set",
- "rise-set",
- "scale-set",
- "size-set",
- "stretch-set",
- "strikethrough-set",
- "style-set",
- "underline-set",
- "variant-set",
- "weight-set",
- NULL
-};
-
-G_DEFINE_TYPE_WITH_CODE (GailTextCell, gail_text_cell, GAIL_TYPE_RENDERER_CELL,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
-
-static void
-gail_text_cell_class_init (GailTextCellClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
- GailRendererCellClass *renderer_cell_class = GAIL_RENDERER_CELL_CLASS (klass);
-
- renderer_cell_class->update_cache = gail_text_cell_update_cache;
- renderer_cell_class->property_list = gail_text_cell_property_list;
-
- atk_object_class->get_name = gail_text_cell_get_name;
-
- gobject_class->finalize = gail_text_cell_finalize;
-}
-
-/* atktext.h */
-
-static void
-gail_text_cell_init (GailTextCell *text_cell)
-{
- text_cell->cell_text = NULL;
- text_cell->caret_pos = 0;
- text_cell->cell_length = 0;
- text_cell->textutil = gail_text_util_new ();
- atk_state_set_add_state (GAIL_CELL (text_cell)->state_set,
- ATK_STATE_SINGLE_LINE);
-}
-
-AtkObject*
-gail_text_cell_new (void)
-{
- GObject *object;
- AtkObject *atk_object;
- GailRendererCell *cell;
-
- object = g_object_new (GAIL_TYPE_TEXT_CELL, NULL);
-
- g_return_val_if_fail (object != NULL, NULL);
-
- atk_object = ATK_OBJECT (object);
- atk_object->role = ATK_ROLE_TABLE_CELL;
-
- cell = GAIL_RENDERER_CELL(object);
-
- cell->renderer = gtk_cell_renderer_text_new ();
- g_object_ref_sink (cell->renderer);
- return atk_object;
-}
-
-static void
-gail_text_cell_finalize (GObject *object)
-{
- GailTextCell *text_cell = GAIL_TEXT_CELL (object);
-
- g_object_unref (text_cell->textutil);
- g_free (text_cell->cell_text);
-
- G_OBJECT_CLASS (gail_text_cell_parent_class)->finalize (object);
-}
-
-static const gchar*
-gail_text_cell_get_name (AtkObject *atk_obj)
-{
- if (atk_obj->name)
- return atk_obj->name;
- else
- {
- GailTextCell *text_cell = GAIL_TEXT_CELL (atk_obj);
-
- return text_cell->cell_text;
- }
-}
-
-static gboolean
-gail_text_cell_update_cache (GailRendererCell *cell,
- gboolean emit_change_signal)
-{
- GailTextCell *text_cell = GAIL_TEXT_CELL (cell);
- AtkObject *obj = ATK_OBJECT (cell);
- gboolean rv = FALSE;
- gint temp_length;
- gchar *new_cache;
-
- g_object_get (G_OBJECT (cell->renderer), "text", &new_cache, NULL);
-
- if (text_cell->cell_text)
- {
- /*
- * If the new value is NULL and the old value isn't NULL, then the
- * value has changed.
- */
- if (new_cache == NULL ||
- strcmp (text_cell->cell_text, new_cache))
- {
- g_free (text_cell->cell_text);
- temp_length = text_cell->cell_length;
- text_cell->cell_text = NULL;
- text_cell->cell_length = 0;
- if (emit_change_signal)
- {
- g_signal_emit_by_name (cell, "text_changed::delete", 0, temp_length);
- if (obj->name == NULL)
- g_object_notify (G_OBJECT (obj), "accessible-name");
- }
- if (new_cache)
- rv = TRUE;
- }
- }
- else
- rv = TRUE;
-
- if (rv)
- {
- if (new_cache == NULL)
- {
- text_cell->cell_text = g_strdup ("");
- text_cell->cell_length = 0;
- }
- else
- {
- text_cell->cell_text = g_strdup (new_cache);
- text_cell->cell_length = g_utf8_strlen (new_cache, -1);
- }
- }
-
- g_free (new_cache);
- gail_text_util_text_setup (text_cell->textutil, text_cell->cell_text);
-
- if (rv)
- {
- if (emit_change_signal)
- {
- g_signal_emit_by_name (cell, "text_changed::insert",
- 0, text_cell->cell_length);
-
- if (obj->name == NULL)
- g_object_notify (G_OBJECT (obj), "accessible-name");
- }
- }
- return rv;
-}
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_text_cell_get_text;
- iface->get_character_at_offset = gail_text_cell_get_character_at_offset;
- iface->get_text_before_offset = gail_text_cell_get_text_before_offset;
- iface->get_text_at_offset = gail_text_cell_get_text_at_offset;
- iface->get_text_after_offset = gail_text_cell_get_text_after_offset;
- iface->get_character_count = gail_text_cell_get_character_count;
- iface->get_caret_offset = gail_text_cell_get_caret_offset;
- iface->set_caret_offset = gail_text_cell_set_caret_offset;
- iface->get_run_attributes = gail_text_cell_get_run_attributes;
- iface->get_default_attributes = gail_text_cell_get_default_attributes;
- iface->get_character_extents = gail_text_cell_get_character_extents;
- iface->get_offset_at_point = gail_text_cell_get_offset_at_point;
-}
-
-static gchar*
-gail_text_cell_get_text (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- if (GAIL_TEXT_CELL (text)->cell_text)
- return gail_text_util_get_substring (GAIL_TEXT_CELL (text)->textutil,
- start_pos, end_pos);
- else
- return g_strdup ("");
-}
-
-static gchar*
-gail_text_cell_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- return gail_text_util_get_text (GAIL_TEXT_CELL (text)->textutil,
- NULL, GAIL_BEFORE_OFFSET, boundary_type, offset, start_offset,
- end_offset);
-}
-
-static gchar*
-gail_text_cell_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- return gail_text_util_get_text (GAIL_TEXT_CELL (text)->textutil,
- NULL, GAIL_AT_OFFSET, boundary_type, offset, start_offset, end_offset);
-}
-
-static gchar*
-gail_text_cell_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- return gail_text_util_get_text (GAIL_TEXT_CELL (text)->textutil,
- NULL, GAIL_AFTER_OFFSET, boundary_type, offset, start_offset,
- end_offset);
-}
-
-static gint
-gail_text_cell_get_character_count (AtkText *text)
-{
- if (GAIL_TEXT_CELL (text)->cell_text != NULL)
- return GAIL_TEXT_CELL (text)->cell_length;
- else
- return 0;
-}
-
-static gint
-gail_text_cell_get_caret_offset (AtkText *text)
-{
- return GAIL_TEXT_CELL (text)->caret_pos;
-}
-
-static gboolean
-gail_text_cell_set_caret_offset (AtkText *text,
- gint offset)
-{
- GailTextCell *text_cell = GAIL_TEXT_CELL (text);
-
- if (text_cell->cell_text == NULL)
- return FALSE;
- else
- {
-
- /* Only set the caret within the bounds and if it is to a new position. */
- if (offset >= 0 &&
- offset <= text_cell->cell_length &&
- offset != text_cell->caret_pos)
- {
- text_cell->caret_pos = offset;
-
- /* emit the signal */
- g_signal_emit_by_name (text, "text_caret_moved", offset);
- return TRUE;
- }
- else
- return FALSE;
- }
-}
-
-static AtkAttributeSet*
-gail_text_cell_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GailRendererCell *gail_renderer;
- GtkCellRendererText *gtk_renderer;
- AtkAttributeSet *attrib_set = NULL;
- PangoLayout *layout;
- AtkObject *parent;
- GtkWidget *widget;
- gchar *renderer_text;
-
- gail_renderer = GAIL_RENDERER_CELL (text);
- gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
-
- parent = atk_object_get_parent (ATK_OBJECT (text));
- if (GAIL_IS_CONTAINER_CELL (parent))
- parent = atk_object_get_parent (parent);
- g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), NULL);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
- layout = create_pango_layout (gtk_renderer, widget),
- g_object_get (gtk_renderer, "text", &renderer_text, NULL);
- attrib_set = gail_misc_layout_get_run_attributes (attrib_set,
- layout,
- renderer_text,
- offset,
- start_offset,
- end_offset);
- g_free (renderer_text);
- g_object_unref (G_OBJECT (layout));
-
- return attrib_set;
-}
-
-static AtkAttributeSet*
-gail_text_cell_get_default_attributes (AtkText *text)
-{
- GailRendererCell *gail_renderer;
- GtkCellRendererText *gtk_renderer;
- AtkAttributeSet *attrib_set = NULL;
- PangoLayout *layout;
- AtkObject *parent;
- GtkWidget *widget;
-
- gail_renderer = GAIL_RENDERER_CELL (text);
- gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
-
- parent = atk_object_get_parent (ATK_OBJECT (text));
- if (GAIL_IS_CONTAINER_CELL (parent))
- parent = atk_object_get_parent (parent);
- g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), NULL);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
- layout = create_pango_layout (gtk_renderer, widget),
-
- attrib_set = gail_misc_get_default_attributes (attrib_set,
- layout,
- widget);
- g_object_unref (G_OBJECT (layout));
- return attrib_set;
-}
-
-/*
- * This function is used by gail_text_cell_get_offset_at_point()
- * and gail_text_cell_get_character_extents(). There is no
- * cached PangoLayout for gailtextcell so we must create a temporary
- * one using this function.
- */
-static PangoLayout*
-create_pango_layout(GtkCellRendererText *gtk_renderer,
- GtkWidget *widget)
-{
- GdkRGBA *foreground_rgba;
- PangoAttrList *attr_list, *attributes;
- PangoLayout *layout;
- PangoUnderline uline, underline;
- PangoFontMask mask;
- PangoFontDescription *font_desc;
- gboolean foreground_set, strikethrough_set, strikethrough;
- gboolean scale_set, underline_set, rise_set;
- gchar *renderer_text;
- gdouble scale;
- gint rise;
-
- g_object_get (gtk_renderer,
- "text", &renderer_text,
- "attributes", &attributes,
- "foreground-set", &foreground_set,
- "foreground-rgba", &foreground_rgba,
- "strikethrough-set", &strikethrough_set,
- "strikethrough", &strikethrough,
- "font-desc", &font_desc,
- "scale-set", &scale_set,
- "scale", &scale,
- "underline-set", &underline_set,
- "underline", &underline,
- "rise-set", &rise_set,
- "rise", &rise,
- NULL);
-
- layout = gtk_widget_create_pango_layout (widget, renderer_text);
-
- if (attributes)
- attr_list = pango_attr_list_copy (attributes);
- else
- attr_list = pango_attr_list_new ();
-
- if (foreground_set)
- {
- add_attr (attr_list, pango_attr_foreground_new (foreground_rgba->red * 65535,
- foreground_rgba->green * 65535,
- foreground_rgba->blue * 65535));
- }
-
- if (strikethrough_set)
- add_attr (attr_list,
- pango_attr_strikethrough_new (strikethrough));
-
- mask = pango_font_description_get_set_fields (font_desc);
-
- if (mask & PANGO_FONT_MASK_FAMILY)
- add_attr (attr_list,
- pango_attr_family_new (pango_font_description_get_family (font_desc)));
-
- if (mask & PANGO_FONT_MASK_STYLE)
- add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (font_desc)));
-
- if (mask & PANGO_FONT_MASK_VARIANT)
- add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (font_desc)));
-
- if (mask & PANGO_FONT_MASK_WEIGHT)
- add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (font_desc)));
-
- if (mask & PANGO_FONT_MASK_STRETCH)
- add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (font_desc)));
-
- if (mask & PANGO_FONT_MASK_SIZE)
- add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (font_desc)));
-
- if (scale_set && scale != 1.0)
- add_attr (attr_list, pango_attr_scale_new (scale));
-
- if (underline_set)
- uline = underline;
- else
- uline = PANGO_UNDERLINE_NONE;
-
- if (uline != PANGO_UNDERLINE_NONE)
- add_attr (attr_list,
- pango_attr_underline_new (underline));
-
- if (rise_set)
- add_attr (attr_list, pango_attr_rise_new (rise));
-
- pango_layout_set_attributes (layout, attr_list);
- pango_layout_set_width (layout, -1);
- pango_attr_list_unref (attr_list);
-
- pango_font_description_free (font_desc);
- pango_attr_list_unref (attributes);
- g_free (renderer_text);
- gdk_rgba_free (foreground_rgba);
-
- return layout;
-}
-
-static void
-add_attr (PangoAttrList *attr_list,
- PangoAttribute *attr)
-{
- attr->start_index = 0;
- attr->end_index = G_MAXINT;
- pango_attr_list_insert (attr_list, attr);
-}
-
-static void
-gail_text_cell_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GailRendererCell *gail_renderer;
- GtkRequisition min_size;
- GtkCellRendererText *gtk_renderer;
- GdkRectangle rendered_rect;
- GtkWidget *widget;
- AtkObject *parent;
- PangoRectangle char_rect;
- PangoLayout *layout;
- gchar *renderer_text;
- gfloat xalign, yalign;
- gint x_offset, y_offset, index;
- gint xpad, ypad;
-
- if (!GAIL_TEXT_CELL (text)->cell_text)
- {
- *x = *y = *height = *width = 0;
- return;
- }
- if (offset < 0 || offset >= GAIL_TEXT_CELL (text)->cell_length)
- {
- *x = *y = *height = *width = 0;
- return;
- }
- gail_renderer = GAIL_RENDERER_CELL (text);
- gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
- /*
- * Thus would be inconsistent with the cache
- */
- g_object_get (gtk_renderer, "text", &renderer_text, NULL);
- if (text == NULL)
- {
- g_free (renderer_text);
- return;
- }
-
- parent = atk_object_get_parent (ATK_OBJECT (text));
- if (GAIL_IS_CONTAINER_CELL (parent))
- parent = atk_object_get_parent (parent);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
- g_return_if_fail (GAIL_IS_CELL_PARENT (parent));
- gail_cell_parent_get_cell_area (GAIL_CELL_PARENT (parent), GAIL_CELL (text),
- &rendered_rect);
-
- gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
- widget,
- &min_size, NULL);
-
- gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
- xalign = 1.0 - xalign;
- x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
- y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));
-
- layout = create_pango_layout (gtk_renderer, widget);
-
- index = g_utf8_offset_to_pointer (renderer_text, offset) - renderer_text;
- pango_layout_index_to_pos (layout, index, &char_rect);
-
- gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);
- gail_misc_get_extents_from_pango_rectangle (widget,
- &char_rect,
- x_offset + rendered_rect.x + xpad,
- y_offset + rendered_rect.y + ypad,
- x, y, width, height, coords);
-
- g_free (renderer_text);
- g_object_unref (layout);
-
- return;
-}
-
-static gint
-gail_text_cell_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- AtkObject *parent;
- GailRendererCell *gail_renderer;
- GtkCellRendererText *gtk_renderer;
- GtkRequisition min_size;
- GtkWidget *widget;
- GdkRectangle rendered_rect;
- PangoLayout *layout;
- gchar *renderer_text;
- gfloat xalign, yalign;
- gint x_offset, y_offset, index;
- gint xpad, ypad;
-
- if (!GAIL_TEXT_CELL (text)->cell_text)
- return -1;
-
- gail_renderer = GAIL_RENDERER_CELL (text);
- gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
- parent = atk_object_get_parent (ATK_OBJECT (text));
-
- g_object_get (gtk_renderer, "text", &renderer_text, NULL);
- if (text == NULL)
- {
- g_free (renderer_text);
- return -1;
- }
-
- if (GAIL_IS_CONTAINER_CELL (parent))
- parent = atk_object_get_parent (parent);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
-
- g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), -1);
- gail_cell_parent_get_cell_area (GAIL_CELL_PARENT (parent), GAIL_CELL (text),
- &rendered_rect);
-
- gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
- widget,
- &min_size, NULL);
- gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
- xalign = 1.0 - xalign;
- x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
- y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));
-
- layout = create_pango_layout (gtk_renderer, widget);
-
- gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);
- index = gail_misc_get_index_at_point_in_layout (widget, layout,
- x_offset + rendered_rect.x + xpad,
- y_offset + rendered_rect.y + ypad,
- x, y, coords);
- g_object_unref (layout);
- if (index == -1)
- {
- if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
- {
- glong length;
-
- length = g_utf8_strlen (renderer_text, -1);
- g_free (renderer_text);
-
- return length;
- }
-
- g_free (renderer_text);
-
- return index;
- }
- else
- {
- glong offset;
-
- offset = g_utf8_pointer_to_offset (renderer_text,
- renderer_text + index);
- g_free (renderer_text);
-
- return offset;
- }
-}
-
-static gunichar
-gail_text_cell_get_character_at_offset (AtkText *text,
- gint offset)
-{
- gchar *index;
- gchar *string;
-
- string = GAIL_TEXT_CELL(text)->cell_text;
-
- if (!string)
- return '\0';
-
- if (offset >= g_utf8_strlen (string, -1))
- return '\0';
-
- index = g_utf8_offset_to_pointer (string, offset);
-
- return g_utf8_get_char (index);
-}
-
+++ /dev/null
-/* GAIL - The GNOME Accessibility Enabling Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_TEXT_CELL_H__
-#define __GAIL_TEXT_CELL_H__
-
-#include <atk/atk.h>
-#include "gailrenderercell.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_TEXT_CELL (gail_text_cell_get_type ())
-#define GAIL_TEXT_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TEXT_CELL, GailTextCell))
-#define GAIL_TEXT_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TEXT_CELL, GailTextCellClass))
-#define GAIL_IS_TEXT_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TEXT_CELL))
-#define GAIL_IS_TEXT_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TEXT_CELL))
-#define GAIL_TEXT_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TEXT_CELL, GailTextCellClass))
-
-typedef struct _GailTextCell GailTextCell;
-typedef struct _GailTextCellClass GailTextCellClass;
-
-struct _GailTextCell
-{
- GailRendererCell parent;
- GailTextUtil *textutil;
- gchar *cell_text;
- gint caret_pos;
- gint cell_length;
-};
-
-GType gail_text_cell_get_type (void);
-
-struct _GailTextCellClass
-{
- GailRendererCellClass parent_class;
-};
-
-AtkObject *gail_text_cell_new (void);
-
-G_END_DECLS
-
-#endif /* __GAIL_TREE_VIEW_TEXT_CELL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <glib-object.h>
-#include <glib/gstdio.h>
-#include <gtk/gtk.h>
-#include "gailtextview.h"
-#include <libgail-util/gailmisc.h>
-
-static void gail_text_view_class_init (GailTextViewClass *klass);
-static void gail_text_view_init (GailTextView *text_view);
-
-static void gail_text_view_real_initialize (AtkObject *obj,
- gpointer data);
-static void gail_text_view_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-
-static void gail_text_view_finalize (GObject *object);
-
-static void atk_text_interface_init (AtkTextIface *iface);
-
-/* atkobject.h */
-
-static AtkStateSet* gail_text_view_ref_state_set (AtkObject *accessible);
-
-/* atktext.h */
-
-static gchar* gail_text_view_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_text_view_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_text_view_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset);
-static gchar* gail_text_view_get_text (AtkText*text,
- gint start_offset,
- gint end_offset);
-static gunichar gail_text_view_get_character_at_offset (AtkText *text,
- gint offset);
-static gint gail_text_view_get_character_count (AtkText *text);
-static gint gail_text_view_get_caret_offset (AtkText *text);
-static gboolean gail_text_view_set_caret_offset (AtkText *text,
- gint offset);
-static gint gail_text_view_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords);
-static gint gail_text_view_get_n_selections (AtkText *text);
-static gchar* gail_text_view_get_selection (AtkText *text,
- gint selection_num,
- gint *start_offset,
- gint *end_offset);
-static gboolean gail_text_view_add_selection (AtkText *text,
- gint start_offset,
- gint end_offset);
-static gboolean gail_text_view_remove_selection (AtkText *text,
- gint selection_num);
-static gboolean gail_text_view_set_selection (AtkText *text,
- gint selection_num,
- gint start_offset,
- gint end_offset);
-static void gail_text_view_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-static AtkAttributeSet * gail_text_view_get_run_attributes
- (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static AtkAttributeSet * gail_text_view_get_default_attributes
- (AtkText *text);
-/* atkeditabletext.h */
-
-static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
-static gboolean gail_text_view_set_run_attributes (AtkEditableText *text,
- AtkAttributeSet *attrib_set,
- gint start_offset,
- gint end_offset);
-static void gail_text_view_set_text_contents (AtkEditableText *text,
- const gchar *string);
-static void gail_text_view_insert_text (AtkEditableText *text,
- const gchar *string,
- gint length,
- gint *position);
-static void gail_text_view_copy_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos);
-static void gail_text_view_cut_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos);
-static void gail_text_view_delete_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos);
-static void gail_text_view_paste_text (AtkEditableText *text,
- gint position);
-static void gail_text_view_paste_received (GtkClipboard *clipboard,
- const gchar *text,
- gpointer data);
-/* AtkStreamableContent */
-static void atk_streamable_content_interface_init (AtkStreamableContentIface *iface);
-static gint gail_streamable_content_get_n_mime_types (AtkStreamableContent *streamable);
-static const gchar* gail_streamable_content_get_mime_type (AtkStreamableContent *streamable,
- gint i);
-static GIOChannel* gail_streamable_content_get_stream (AtkStreamableContent *streamable,
- const gchar *mime_type);
-/* getURI requires atk-1.12.0 or later
-static void gail_streamable_content_get_uri (AtkStreamableContent *streamable);
-*/
-
-/* Callbacks */
-
-static void _gail_text_view_insert_text_cb (GtkTextBuffer *buffer,
- GtkTextIter *arg1,
- gchar *arg2,
- gint arg3,
- gpointer user_data);
-static void _gail_text_view_delete_range_cb (GtkTextBuffer *buffer,
- GtkTextIter *arg1,
- GtkTextIter *arg2,
- gpointer user_data);
-static void _gail_text_view_changed_cb (GtkTextBuffer *buffer,
- gpointer user_data);
-static void _gail_text_view_mark_set_cb (GtkTextBuffer *buffer,
- GtkTextIter *arg1,
- GtkTextMark *arg2,
- gpointer user_data);
-static gchar* get_text_near_offset (AtkText *text,
- GailOffsetType function,
- AtkTextBoundary boundary_type,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-static gint get_insert_offset (GtkTextBuffer *buffer);
-static gint get_selection_bound (GtkTextBuffer *buffer);
-static void emit_text_caret_moved (GailTextView *gail_text_view,
- gint insert_offset);
-static gint insert_idle_handler (gpointer data);
-
-typedef struct _GailTextViewPaste GailTextViewPaste;
-
-struct _GailTextViewPaste
-{
- GtkTextBuffer* buffer;
- gint position;
-};
-
-G_DEFINE_TYPE_WITH_CODE (GailTextView, gail_text_view, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_STREAMABLE_CONTENT, atk_streamable_content_interface_init))
-
-static void
-gail_text_view_class_init (GailTextViewClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GailWidgetClass *widget_class;
-
- widget_class = (GailWidgetClass*)klass;
-
- gobject_class->finalize = gail_text_view_finalize;
-
- class->ref_state_set = gail_text_view_ref_state_set;
- class->initialize = gail_text_view_real_initialize;
-
- widget_class->notify_gtk = gail_text_view_real_notify_gtk;
-}
-
-static void
-gail_text_view_init (GailTextView *text_view)
-{
- text_view->textutil = NULL;
- text_view->signal_name = NULL;
- text_view->previous_insert_offset = -1;
- text_view->previous_selection_bound = -1;
- text_view->insert_notify_handler = 0;
-}
-
-static void
-setup_buffer (GtkTextView *view,
- GailTextView *gail_view)
-{
- GtkTextBuffer *buffer;
-
- buffer = gtk_text_view_get_buffer (view);
-
- if (gail_view->textutil)
- g_object_unref (gail_view->textutil);
-
- gail_view->textutil = gail_text_util_new ();
- gail_text_util_buffer_setup (gail_view->textutil, buffer);
-
- /* Set up signal callbacks */
- g_signal_connect_data (buffer, "insert-text",
- (GCallback) _gail_text_view_insert_text_cb, view, NULL, 0);
- g_signal_connect_data (buffer, "delete-range",
- (GCallback) _gail_text_view_delete_range_cb, view, NULL, 0);
- g_signal_connect_data (buffer, "mark-set",
- (GCallback) _gail_text_view_mark_set_cb, view, NULL, 0);
- g_signal_connect_data (buffer, "changed",
- (GCallback) _gail_text_view_changed_cb, view, NULL, 0);
-
-}
-
-static void
-gail_text_view_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkTextView *view;
- GailTextView *gail_view;
-
- ATK_OBJECT_CLASS (gail_text_view_parent_class)->initialize (obj, data);
-
- view = GTK_TEXT_VIEW (data);
-
- gail_view = GAIL_TEXT_VIEW (obj);
- setup_buffer (view, gail_view);
-
- obj->role = ATK_ROLE_TEXT;
-
-}
-
-static void
-gail_text_view_finalize (GObject *object)
-{
- GailTextView *text_view = GAIL_TEXT_VIEW (object);
-
- g_object_unref (text_view->textutil);
- if (text_view->insert_notify_handler)
- g_source_remove (text_view->insert_notify_handler);
-
- G_OBJECT_CLASS (gail_text_view_parent_class)->finalize (object);
-}
-
-static void
-gail_text_view_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- if (!strcmp (pspec->name, "editable"))
- {
- AtkObject *atk_obj;
- gboolean editable;
-
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj));
- editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (obj));
- atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE,
- editable);
- }
- else if (!strcmp (pspec->name, "buffer"))
- {
- AtkObject *atk_obj;
-
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj));
- setup_buffer (GTK_TEXT_VIEW (obj), GAIL_TEXT_VIEW (atk_obj));
- }
- else
- GAIL_WIDGET_CLASS (gail_text_view_parent_class)->notify_gtk (obj, pspec);
-}
-
-/* atkobject.h */
-
-static AtkStateSet*
-gail_text_view_ref_state_set (AtkObject *accessible)
-{
- AtkStateSet *state_set;
- GtkTextView *text_view;
- GtkWidget *widget;
-
- state_set = ATK_OBJECT_CLASS (gail_text_view_parent_class)->ref_state_set (accessible);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- return state_set;
-
- text_view = GTK_TEXT_VIEW (widget);
-
- if (gtk_text_view_get_editable (text_view))
- atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
- atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
-
- return state_set;
-}
-
-/* atktext.h */
-
-static void
-atk_text_interface_init (AtkTextIface *iface)
-{
- iface->get_text = gail_text_view_get_text;
- iface->get_text_after_offset = gail_text_view_get_text_after_offset;
- iface->get_text_at_offset = gail_text_view_get_text_at_offset;
- iface->get_text_before_offset = gail_text_view_get_text_before_offset;
- iface->get_character_at_offset = gail_text_view_get_character_at_offset;
- iface->get_character_count = gail_text_view_get_character_count;
- iface->get_caret_offset = gail_text_view_get_caret_offset;
- iface->set_caret_offset = gail_text_view_set_caret_offset;
- iface->get_offset_at_point = gail_text_view_get_offset_at_point;
- iface->get_character_extents = gail_text_view_get_character_extents;
- iface->get_n_selections = gail_text_view_get_n_selections;
- iface->get_selection = gail_text_view_get_selection;
- iface->add_selection = gail_text_view_add_selection;
- iface->remove_selection = gail_text_view_remove_selection;
- iface->set_selection = gail_text_view_set_selection;
- iface->get_run_attributes = gail_text_view_get_run_attributes;
- iface->get_default_attributes = gail_text_view_get_default_attributes;
-}
-
-static gchar*
-gail_text_view_get_text (AtkText *text,
- gint start_offset,
- gint end_offset)
-{
- GtkTextView *view;
- GtkTextBuffer *buffer;
- GtkTextIter start, end;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
- gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
- gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
-
- return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
-}
-
-static gchar*
-gail_text_view_get_text_after_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- return get_text_near_offset (text, GAIL_AFTER_OFFSET,
- boundary_type, offset,
- start_offset, end_offset);
-}
-
-static gchar*
-gail_text_view_get_text_at_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- return get_text_near_offset (text, GAIL_AT_OFFSET,
- boundary_type, offset,
- start_offset, end_offset);
-}
-
-static gchar*
-gail_text_view_get_text_before_offset (AtkText *text,
- gint offset,
- AtkTextBoundary boundary_type,
- gint *start_offset,
- gint *end_offset)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- return get_text_near_offset (text, GAIL_BEFORE_OFFSET,
- boundary_type, offset,
- start_offset, end_offset);
-}
-
-static gunichar
-gail_text_view_get_character_at_offset (AtkText *text,
- gint offset)
-{
- GtkWidget *widget;
- GtkTextIter start, end;
- GtkTextBuffer *buffer;
- gchar *string;
- gunichar unichar;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- return '\0';
-
- buffer = GAIL_TEXT_VIEW (text)->textutil->buffer;
- if (offset >= gtk_text_buffer_get_char_count (buffer))
- return '\0';
-
- gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
- end = start;
- gtk_text_iter_forward_char (&end);
- string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
- unichar = g_utf8_get_char (string);
- g_free(string);
- return unichar;
-}
-
-static gint
-gail_text_view_get_character_count (AtkText *text)
-{
- GtkTextView *view;
- GtkTextBuffer *buffer;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
- return gtk_text_buffer_get_char_count (buffer);
-}
-
-static gint
-gail_text_view_get_caret_offset (AtkText *text)
-{
- GtkTextView *view;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- view = GTK_TEXT_VIEW (widget);
- return get_insert_offset (gtk_text_view_get_buffer (view));
-}
-
-static gboolean
-gail_text_view_set_caret_offset (AtkText *text,
- gint offset)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextIter pos_itr;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, offset);
- gtk_text_buffer_place_cursor (buffer, &pos_itr);
- gtk_text_view_scroll_to_iter (view, &pos_itr, 0, FALSE, 0, 0);
- return TRUE;
-}
-
-static gint
-gail_text_view_get_offset_at_point (AtkText *text,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- GtkTextView *view;
- GtkTextIter loc_itr;
- gint x_widget, y_widget, x_window, y_window, buff_x, buff_y;
- GtkWidget *widget;
- GdkWindow *window;
- GdkRectangle rect;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- view = GTK_TEXT_VIEW (widget);
-
- window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
- gdk_window_get_origin (window, &x_widget, &y_widget);
-
- if (coords == ATK_XY_SCREEN)
- {
- x = x - x_widget;
- y = y - y_widget;
- }
- else if (coords == ATK_XY_WINDOW)
- {
- window = gdk_window_get_toplevel (window);
- gdk_window_get_origin (window, &x_window, &y_window);
-
- x = x - x_widget + x_window;
- y = y - y_widget + y_window;
- }
- else
- return -1;
-
- gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_WIDGET,
- x, y, &buff_x, &buff_y);
- gtk_text_view_get_visible_rect (view, &rect);
- /*
- * Clamp point to visible rectangle
- */
- buff_x = CLAMP (buff_x, rect.x, rect.x + rect.width - 1);
- buff_y = CLAMP (buff_y, rect.y, rect.y + rect.height - 1);
-
- gtk_text_view_get_iter_at_location (view, &loc_itr, buff_x, buff_y);
- /*
- * The iter at a location sometimes points to the next character.
- * See bug 111031. We work around that
- */
- gtk_text_view_get_iter_location (view, &loc_itr, &rect);
- if (buff_x < rect.x)
- gtk_text_iter_backward_char (&loc_itr);
- return gtk_text_iter_get_offset (&loc_itr);
-}
-
-static void
-gail_text_view_get_character_extents (AtkText *text,
- gint offset,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- GtkTextView *view;
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- GtkWidget *widget;
- GdkRectangle rectangle;
- GdkWindow *window;
- gint x_widget, y_widget, x_window, y_window;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
- gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
- gtk_text_view_get_iter_location (view, &iter, &rectangle);
-
- window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
- gdk_window_get_origin (window, &x_widget, &y_widget);
-
- *height = rectangle.height;
- *width = rectangle.width;
-
- gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_WIDGET,
- rectangle.x, rectangle.y, x, y);
- if (coords == ATK_XY_WINDOW)
- {
- window = gdk_window_get_toplevel (window);
- gdk_window_get_origin (window, &x_window, &y_window);
- *x += x_widget - x_window;
- *y += y_widget - y_window;
- }
- else if (coords == ATK_XY_SCREEN)
- {
- *x += x_widget;
- *y += y_widget;
- }
- else
- {
- *x = 0;
- *y = 0;
- *height = 0;
- *width = 0;
- }
-}
-
-static AtkAttributeSet*
-gail_text_view_get_run_attributes (AtkText *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkTextView *view;
- GtkTextBuffer *buffer;
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
-
- return gail_misc_buffer_get_run_attributes (buffer, offset,
- start_offset, end_offset);
-}
-
-static AtkAttributeSet*
-add_text_attribute (AtkAttributeSet *attrib_set, AtkTextAttribute attr, gint i)
-{
- const gchar *value;
-
- value = atk_text_attribute_get_value (attr, i);
-
- return gail_misc_add_attribute (attrib_set, i, g_strdup (value));
-}
-
-static AtkAttributeSet*
-gail_text_view_get_default_attributes (AtkText *text)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextAttributes *text_attrs;
- AtkAttributeSet *attrib_set = NULL;
- PangoFontDescription *font;
- gchar *value;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- view = GTK_TEXT_VIEW (widget);
- text_attrs = gtk_text_view_get_default_attributes (view);
-
- font = text_attrs->font;
-
- if (font)
- {
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_STYLE,
- pango_font_description_get_style (font));
-
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT,
- pango_font_description_get_variant (font));
-
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH,
- pango_font_description_get_stretch (font));
-
- value = g_strdup (pango_font_description_get_family (font));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
-
- value = g_strdup_printf ("%d", pango_font_description_get_weight (font));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
-
- value = g_strdup_printf ("%i", pango_font_description_get_size (font) / PANGO_SCALE);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
- }
-
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, text_attrs->justification);
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, text_attrs->direction);
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, text_attrs->wrap_mode);
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, text_attrs->editable);
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, text_attrs->invisible);
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, text_attrs->bg_full_height);
-
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH,
- text_attrs->appearance.strikethrough);
- attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE,
- text_attrs->appearance.underline);
-
- value = g_strdup_printf ("%u,%u,%u",
- text_attrs->appearance.bg_color.red,
- text_attrs->appearance.bg_color.green,
- text_attrs->appearance.bg_color.blue);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
-
- value = g_strdup_printf ("%u,%u,%u",
- text_attrs->appearance.fg_color.red,
- text_attrs->appearance.fg_color.green,
- text_attrs->appearance.fg_color.blue);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
-
- value = g_strdup_printf ("%g", text_attrs->font_scale);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_SCALE, value);
-
- value = g_strdup ((gchar *)(text_attrs->language));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
-
- value = g_strdup_printf ("%i", text_attrs->appearance.rise);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
-
- value = g_strdup_printf ("%i", text_attrs->pixels_inside_wrap);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
-
- value = g_strdup_printf ("%i", text_attrs->pixels_below_lines);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
-
- value = g_strdup_printf ("%i", text_attrs->pixels_above_lines);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
-
- value = g_strdup_printf ("%i", text_attrs->indent);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
-
- value = g_strdup_printf ("%i", text_attrs->left_margin);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
-
- value = g_strdup_printf ("%i", text_attrs->right_margin);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
-
- gtk_text_attributes_unref (text_attrs);
- return attrib_set;
-}
-
-static gint
-gail_text_view_get_n_selections (AtkText *text)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextIter start, end;
- gint select_start, select_end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
- select_start = gtk_text_iter_get_offset (&start);
- select_end = gtk_text_iter_get_offset (&end);
-
- if (select_start != select_end)
- return 1;
- else
- return 0;
-}
-
-static gchar*
-gail_text_view_get_selection (AtkText *text,
- gint selection_num,
- gint *start_pos,
- gint *end_pos)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextIter start, end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- /* Only let the user get the selection if one is set, and if the
- * selection_num is 0.
- */
- if (selection_num != 0)
- return NULL;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
- *start_pos = gtk_text_iter_get_offset (&start);
- *end_pos = gtk_text_iter_get_offset (&end);
-
- if (*start_pos != *end_pos)
- return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- else
- return NULL;
-}
-
-static gboolean
-gail_text_view_add_selection (AtkText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextIter pos_itr;
- GtkTextIter start, end;
- gint select_start, select_end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
- select_start = gtk_text_iter_get_offset (&start);
- select_end = gtk_text_iter_get_offset (&end);
-
- /* If there is already a selection, then don't allow another to be added,
- * since GtkTextView only supports one selected region.
- */
- if (select_start == select_end)
- {
- gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, start_pos);
- gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", &pos_itr);
- gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, end_pos);
- gtk_text_buffer_move_mark_by_name (buffer, "insert", &pos_itr);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gboolean
-gail_text_view_remove_selection (AtkText *text,
- gint selection_num)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextMark *cursor_mark;
- GtkTextIter cursor_itr;
- GtkTextIter start, end;
- gint select_start, select_end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- if (selection_num != 0)
- return FALSE;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_selection_bounds(buffer, &start, &end);
- select_start = gtk_text_iter_get_offset(&start);
- select_end = gtk_text_iter_get_offset(&end);
-
- if (select_start != select_end)
- {
- /* Setting the start & end of the selected region to the caret position
- * turns off the selection.
- */
- cursor_mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &cursor_itr, cursor_mark);
- gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", &cursor_itr);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static gboolean
-gail_text_view_set_selection (AtkText *text,
- gint selection_num,
- gint start_pos,
- gint end_pos)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextIter pos_itr;
- GtkTextIter start, end;
- gint select_start, select_end;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- {
- /* State is defunct */
- return FALSE;
- }
-
- /* Only let the user move the selection if one is set, and if the
- * selection_num is 0
- */
- if (selection_num != 0)
- return FALSE;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_selection_bounds(buffer, &start, &end);
- select_start = gtk_text_iter_get_offset(&start);
- select_end = gtk_text_iter_get_offset(&end);
-
- if (select_start != select_end)
- {
- gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, start_pos);
- gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", &pos_itr);
- gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, end_pos);
- gtk_text_buffer_move_mark_by_name (buffer, "insert", &pos_itr);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-/* atkeditabletext.h */
-
-static void
-atk_editable_text_interface_init (AtkEditableTextIface *iface)
-{
- iface->set_text_contents = gail_text_view_set_text_contents;
- iface->insert_text = gail_text_view_insert_text;
- iface->copy_text = gail_text_view_copy_text;
- iface->cut_text = gail_text_view_cut_text;
- iface->delete_text = gail_text_view_delete_text;
- iface->paste_text = gail_text_view_paste_text;
- iface->set_run_attributes = gail_text_view_set_run_attributes;
-}
-
-static gboolean
-gail_text_view_set_run_attributes (AtkEditableText *text,
- AtkAttributeSet *attrib_set,
- gint start_offset,
- gint end_offset)
-{
- GtkTextView *view;
- GtkTextBuffer *buffer;
- GtkWidget *widget;
- GtkTextTag *tag;
- GtkTextIter start;
- GtkTextIter end;
- gint j;
- GdkColor *color;
- gchar** RGB_vals;
- GSList *l;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- view = GTK_TEXT_VIEW (widget);
- if (!gtk_text_view_get_editable (view))
- return FALSE;
-
- buffer = gtk_text_view_get_buffer (view);
-
- if (attrib_set == NULL)
- return FALSE;
-
- gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
- gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
-
- tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
-
- for (l = attrib_set; l; l = l->next)
- {
- gchar *name;
- gchar *value;
- AtkAttribute *at;
-
- at = l->data;
-
- name = at->name;
- value = at->value;
-
- if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LEFT_MARGIN)))
- g_object_set (G_OBJECT (tag), "left_margin", atoi (value), NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RIGHT_MARGIN)))
- g_object_set (G_OBJECT (tag), "right_margin", atoi (value), NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INDENT)))
- g_object_set (G_OBJECT (tag), "indent", atoi (value), NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_ABOVE_LINES)))
- g_object_set (G_OBJECT (tag), "pixels_above_lines", atoi (value), NULL);
-
- else if (!strcmp(name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_BELOW_LINES)))
- g_object_set (G_OBJECT (tag), "pixels_below_lines", atoi (value), NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP)))
- g_object_set (G_OBJECT (tag), "pixels_inside_wrap", atoi (value), NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_SIZE)))
- g_object_set (G_OBJECT (tag), "size", atoi (value), NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RISE)))
- g_object_set (G_OBJECT (tag), "rise", atoi (value), NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WEIGHT)))
- g_object_set (G_OBJECT (tag), "weight", atoi (value), NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_FULL_HEIGHT)))
- {
- g_object_set (G_OBJECT (tag), "bg_full_height",
- (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, 0))),
- NULL);
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LANGUAGE)))
- g_object_set (G_OBJECT (tag), "language", value, NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FAMILY_NAME)))
- g_object_set (G_OBJECT (tag), "family", value, NULL);
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_EDITABLE)))
- {
- g_object_set (G_OBJECT (tag), "editable",
- (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
- NULL);
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INVISIBLE)))
- {
- g_object_set (G_OBJECT (tag), "invisible",
- (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
- NULL);
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_UNDERLINE)))
- {
- for (j = 0; j < 3; j++)
- {
- if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, j)))
- {
- g_object_set (G_OBJECT (tag), "underline", j, NULL);
- break;
- }
- }
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRIKETHROUGH)))
- {
- g_object_set (G_OBJECT (tag), "strikethrough",
- (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, 0))),
- NULL);
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_COLOR)))
- {
- RGB_vals = g_strsplit (value, ",", 3);
- color = g_malloc (sizeof (GdkColor));
- color->red = atoi (RGB_vals[0]);
- color->green = atoi (RGB_vals[1]);
- color->blue = atoi (RGB_vals[2]);
- g_object_set (G_OBJECT (tag), "background_gdk", color, NULL);
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FG_COLOR)))
- {
- RGB_vals = g_strsplit (value, ",", 3);
- color = g_malloc (sizeof (GdkColor));
- color->red = atoi (RGB_vals[0]);
- color->green = atoi (RGB_vals[1]);
- color->blue = atoi (RGB_vals[2]);
- g_object_set (G_OBJECT (tag), "foreground_gdk", color, NULL);
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRETCH)))
- {
- for (j = 0; j < 9; j++)
- {
- if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, j)))
- {
- g_object_set (G_OBJECT (tag), "stretch", j, NULL);
- break;
- }
- }
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_JUSTIFICATION)))
- {
- for (j = 0; j < 4; j++)
- {
- if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, j)))
- {
- g_object_set (G_OBJECT (tag), "justification", j, NULL);
- break;
- }
- }
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_DIRECTION)))
- {
- for (j = 0; j < 3; j++)
- {
- if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, j)))
- {
- g_object_set (G_OBJECT (tag), "direction", j, NULL);
- break;
- }
- }
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_VARIANT)))
- {
- for (j = 0; j < 2; j++)
- {
- if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, j)))
- {
- g_object_set (G_OBJECT (tag), "variant", j, NULL);
- break;
- }
- }
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WRAP_MODE)))
- {
- for (j = 0; j < 3; j++)
- {
- if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, j)))
- {
- g_object_set (G_OBJECT (tag), "wrap_mode", j, NULL);
- break;
- }
- }
- }
-
- else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STYLE)))
- {
- for (j = 0; j < 3; j++)
- {
- if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, j)))
- {
- g_object_set (G_OBJECT (tag), "style", j, NULL);
- break;
- }
- }
- }
-
- else
- return FALSE;
- }
-
- gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
-
- return TRUE;
-}
-
-static void
-gail_text_view_set_text_contents (AtkEditableText *text,
- const gchar *string)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- view = GTK_TEXT_VIEW (widget);
- if (!gtk_text_view_get_editable (view))
- return;
- buffer = gtk_text_view_get_buffer (view);
-
- /* The -1 indicates that the input string must be null-terminated */
- gtk_text_buffer_set_text (buffer, string, -1);
-}
-
-static void
-gail_text_view_insert_text (AtkEditableText *text,
- const gchar *string,
- gint length,
- gint *position)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextIter pos_itr;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- view = GTK_TEXT_VIEW (widget);
- if (!gtk_text_view_get_editable (view))
- return;
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_iter_at_offset (buffer, &pos_itr, *position);
- gtk_text_buffer_insert (buffer, &pos_itr, string, length);
-}
-
-static void
-gail_text_view_copy_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextIter start, end;
- gchar *str;
- GtkClipboard *clipboard;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- view = GTK_TEXT_VIEW (widget);
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
- gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
- str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
- GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text (clipboard, str, -1);
-}
-
-static void
-gail_text_view_cut_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextIter start, end;
- gchar *str;
- GtkClipboard *clipboard;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- view = GTK_TEXT_VIEW (widget);
- if (!gtk_text_view_get_editable (view))
- return;
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
- gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
- str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
- GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text (clipboard, str, -1);
- gtk_text_buffer_delete (buffer, &start, &end);
-}
-
-static void
-gail_text_view_delete_text (AtkEditableText *text,
- gint start_pos,
- gint end_pos)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GtkTextIter start_itr;
- GtkTextIter end_itr;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- view = GTK_TEXT_VIEW (widget);
- if (!gtk_text_view_get_editable (view))
- return;
- buffer = gtk_text_view_get_buffer (view);
-
- gtk_text_buffer_get_iter_at_offset (buffer, &start_itr, start_pos);
- gtk_text_buffer_get_iter_at_offset (buffer, &end_itr, end_pos);
- gtk_text_buffer_delete (buffer, &start_itr, &end_itr);
-}
-
-static void
-gail_text_view_paste_text (AtkEditableText *text,
- gint position)
-{
- GtkTextView *view;
- GtkWidget *widget;
- GtkTextBuffer *buffer;
- GailTextViewPaste paste_struct;
- GtkClipboard *clipboard;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- view = GTK_TEXT_VIEW (widget);
- if (!gtk_text_view_get_editable (view))
- return;
- buffer = gtk_text_view_get_buffer (view);
-
- paste_struct.buffer = buffer;
- paste_struct.position = position;
-
- g_object_ref (paste_struct.buffer);
- clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
- GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_request_text (clipboard,
- gail_text_view_paste_received, &paste_struct);
-}
-
-static void
-gail_text_view_paste_received (GtkClipboard *clipboard,
- const gchar *text,
- gpointer data)
-{
- GailTextViewPaste* paste_struct = (GailTextViewPaste *)data;
- GtkTextIter pos_itr;
-
- if (text)
- {
- gtk_text_buffer_get_iter_at_offset (paste_struct->buffer, &pos_itr,
- paste_struct->position);
- gtk_text_buffer_insert (paste_struct->buffer, &pos_itr, text, -1);
- }
-
- g_object_unref (paste_struct->buffer);
-}
-
-/* Callbacks */
-
-/* Note arg1 returns the start of the insert range, arg3 returns the
- * end of the insert range if multiple characters are inserted. If one
- * character is inserted they have the same value, which is the caret
- * location. arg2 returns the begin location of the insert.
- */
-static void
-_gail_text_view_insert_text_cb (GtkTextBuffer *buffer,
- GtkTextIter *arg1,
- gchar *arg2,
- gint arg3,
- gpointer user_data)
-{
- GtkTextView *text = (GtkTextView *) user_data;
- AtkObject *accessible;
- GailTextView *gail_text_view;
- gint position;
- gint length;
-
- g_return_if_fail (arg3 > 0);
-
- accessible = gtk_widget_get_accessible(GTK_WIDGET(text));
- gail_text_view = GAIL_TEXT_VIEW (accessible);
-
- gail_text_view->signal_name = "text_changed::insert";
- position = gtk_text_iter_get_offset (arg1);
- length = g_utf8_strlen(arg2, arg3);
-
- if (gail_text_view->length == 0)
- {
- gail_text_view->position = position;
- gail_text_view->length = length;
- }
- else if (gail_text_view->position + gail_text_view->length == position)
- {
- gail_text_view->length += length;
- }
- else
- {
- /*
- * We have a non-contiguous insert so report what we have
- */
- if (gail_text_view->insert_notify_handler)
- {
- g_source_remove (gail_text_view->insert_notify_handler);
- }
- gail_text_view->insert_notify_handler = 0;
- insert_idle_handler (gail_text_view);
- gail_text_view->position = position;
- gail_text_view->length = length;
- }
-
- /*
- * The signal will be emitted when the changed signal is received
- */
-}
-
-/* Note arg1 returns the start of the delete range, arg2 returns the
- * end of the delete range if multiple characters are deleted. If one
- * character is deleted they have the same value, which is the caret
- * location.
- */
-static void
-_gail_text_view_delete_range_cb (GtkTextBuffer *buffer,
- GtkTextIter *arg1,
- GtkTextIter *arg2,
- gpointer user_data)
-{
- GtkTextView *text = (GtkTextView *) user_data;
- AtkObject *accessible;
- GailTextView *gail_text_view;
- gint offset = gtk_text_iter_get_offset (arg1);
- gint length = gtk_text_iter_get_offset (arg2) - offset;
-
- accessible = gtk_widget_get_accessible(GTK_WIDGET(text));
- gail_text_view = GAIL_TEXT_VIEW (accessible);
- if (gail_text_view->insert_notify_handler)
- {
- g_source_remove (gail_text_view->insert_notify_handler);
- gail_text_view->insert_notify_handler = 0;
- if (gail_text_view->position == offset &&
- gail_text_view->length == length)
- {
- /*
- * Do not bother with insert and delete notifications
- */
- gail_text_view->signal_name = NULL;
- gail_text_view->position = 0;
- gail_text_view->length = 0;
- return;
- }
-
- insert_idle_handler (gail_text_view);
- }
- g_signal_emit_by_name (accessible, "text_changed::delete",
- offset, length);
-}
-
-/* Note arg1 and arg2 point to the same offset, which is the caret
- * position after the move
- */
-static void
-_gail_text_view_mark_set_cb (GtkTextBuffer *buffer,
- GtkTextIter *arg1,
- GtkTextMark *arg2,
- gpointer user_data)
-{
- GtkTextView *text = (GtkTextView *) user_data;
- AtkObject *accessible;
- GailTextView *gail_text_view;
- const char *mark_name = gtk_text_mark_get_name(arg2);
-
- accessible = gtk_widget_get_accessible(GTK_WIDGET(text));
- gail_text_view = GAIL_TEXT_VIEW (accessible);
-
- /*
- * Only generate the signal for the "insert" mark, which
- * represents the cursor.
- */
- if (mark_name && !strcmp(mark_name, "insert"))
- {
- int insert_offset, selection_bound;
- gboolean selection_changed;
-
- insert_offset = gtk_text_iter_get_offset (arg1);
-
- selection_bound = get_selection_bound (buffer);
- if (selection_bound != insert_offset)
- {
- if (selection_bound != gail_text_view->previous_selection_bound ||
- insert_offset != gail_text_view->previous_insert_offset)
- {
- selection_changed = TRUE;
- }
- else
- {
- selection_changed = FALSE;
- }
- }
- else if (gail_text_view->previous_selection_bound != gail_text_view->previous_insert_offset)
- {
- selection_changed = TRUE;
- }
- else
- {
- selection_changed = FALSE;
- }
-
- emit_text_caret_moved (gail_text_view, insert_offset);
- /*
- * insert and selection_bound marks are different to a selection
- * has changed
- */
- if (selection_changed)
- g_signal_emit_by_name (accessible, "text_selection_changed");
- gail_text_view->previous_selection_bound = selection_bound;
- }
-}
-
-static void
-_gail_text_view_changed_cb (GtkTextBuffer *buffer,
- gpointer user_data)
-{
- GtkTextView *text = (GtkTextView *) user_data;
- AtkObject *accessible;
- GailTextView *gail_text_view;
-
- accessible = gtk_widget_get_accessible (GTK_WIDGET (text));
- gail_text_view = GAIL_TEXT_VIEW (accessible);
- if (gail_text_view->signal_name)
- {
- if (!gail_text_view->insert_notify_handler)
- {
- gail_text_view->insert_notify_handler = gdk_threads_add_idle (insert_idle_handler, accessible);
- }
- return;
- }
- emit_text_caret_moved (gail_text_view, get_insert_offset (buffer));
- gail_text_view->previous_selection_bound = get_selection_bound (buffer);
-}
-
-static gchar*
-get_text_near_offset (AtkText *text,
- GailOffsetType function,
- AtkTextBoundary boundary_type,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkTextView *view;
- gpointer layout = NULL;
-
- view = GTK_TEXT_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (text)));
-
- /*
- * Pass the GtkTextView to the function gail_text_util_get_text()
- * so it can find the start and end of the current line on the display.
- */
- if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START ||
- boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
- layout = view;
-
- return gail_text_util_get_text (GAIL_TEXT_VIEW (text)->textutil, layout,
- function, boundary_type, offset,
- start_offset, end_offset);
-}
-
-static gint
-get_insert_offset (GtkTextBuffer *buffer)
-{
- GtkTextMark *cursor_mark;
- GtkTextIter cursor_itr;
-
- cursor_mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &cursor_itr, cursor_mark);
- return gtk_text_iter_get_offset (&cursor_itr);
-}
-
-static gint
-get_selection_bound (GtkTextBuffer *buffer)
-{
- GtkTextMark *selection_mark;
- GtkTextIter selection_itr;
-
- selection_mark = gtk_text_buffer_get_selection_bound (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &selection_itr, selection_mark);
- return gtk_text_iter_get_offset (&selection_itr);
-}
-
-static void
-emit_text_caret_moved (GailTextView *gail_text_view,
- gint insert_offset)
-{
- /*
- * If we have text which has been inserted notify the user
- */
- if (gail_text_view->insert_notify_handler)
- {
- g_source_remove (gail_text_view->insert_notify_handler);
- gail_text_view->insert_notify_handler = 0;
- insert_idle_handler (gail_text_view);
- }
-
- if (insert_offset != gail_text_view->previous_insert_offset)
- {
- /*
- * If the caret position has not changed then don't bother notifying
- *
- * When mouse click is used to change caret position, notification
- * is received on button down and button up.
- */
- g_signal_emit_by_name (gail_text_view, "text_caret_moved", insert_offset);
- gail_text_view->previous_insert_offset = insert_offset;
- }
-}
-
-static gint
-insert_idle_handler (gpointer data)
-{
- GailTextView *gail_text_view;
- GtkTextBuffer *buffer;
-
- gail_text_view = GAIL_TEXT_VIEW (data);
-
- g_signal_emit_by_name (data,
- gail_text_view->signal_name,
- gail_text_view->position,
- gail_text_view->length);
- gail_text_view->signal_name = NULL;
- gail_text_view->position = 0;
- gail_text_view->length = 0;
-
- buffer = gail_text_view->textutil->buffer;
- if (gail_text_view->insert_notify_handler)
- {
- /*
- * If called from idle handler notify caret moved
- */
- gail_text_view->insert_notify_handler = 0;
- emit_text_caret_moved (gail_text_view, get_insert_offset (buffer));
- gail_text_view->previous_selection_bound = get_selection_bound (buffer);
- }
-
- return FALSE;
-}
-
-static void
-atk_streamable_content_interface_init (AtkStreamableContentIface *iface)
-{
- iface->get_n_mime_types = gail_streamable_content_get_n_mime_types;
- iface->get_mime_type = gail_streamable_content_get_mime_type;
- iface->get_stream = gail_streamable_content_get_stream;
-}
-
-static gint gail_streamable_content_get_n_mime_types (AtkStreamableContent *streamable)
-{
- gint n_mime_types = 0;
-
- if (GAIL_IS_TEXT_VIEW (streamable) && GAIL_TEXT_VIEW (streamable)->textutil)
- {
- int i;
- gboolean advertises_plaintext = FALSE;
- GdkAtom *atoms =
- gtk_text_buffer_get_serialize_formats (
- GAIL_TEXT_VIEW (streamable)->textutil->buffer,
- &n_mime_types);
- for (i = 0; i < n_mime_types-1; ++i)
- if (!strcmp ("text/plain", gdk_atom_name (atoms[i])))
- advertises_plaintext = TRUE;
- if (!advertises_plaintext) ++n_mime_types;
- /* we support text/plain even if the GtkTextBuffer doesn't */
- }
- return n_mime_types;
-}
-
-static const gchar*
-gail_streamable_content_get_mime_type (AtkStreamableContent *streamable, gint i)
-{
- if (GAIL_IS_TEXT_VIEW (streamable) && GAIL_TEXT_VIEW (streamable)->textutil)
- {
- gint n_mime_types = 0;
- GdkAtom *atoms;
- atoms = gtk_text_buffer_get_serialize_formats (
- GAIL_TEXT_VIEW (streamable)->textutil->buffer,
- &n_mime_types);
- if (i < n_mime_types)
- {
- return gdk_atom_name (atoms [i]);
- }
- else if (i == n_mime_types)
- return "text/plain";
- }
- return NULL;
-}
-
-static GIOChannel* gail_streamable_content_get_stream (AtkStreamableContent *streamable,
- const gchar *mime_type)
-{
- gint i, n_mime_types = 0;
- GdkAtom *atoms;
- if (!GAIL_IS_TEXT_VIEW (streamable) || !GAIL_TEXT_VIEW (streamable)->textutil)
- return NULL;
- atoms = gtk_text_buffer_get_serialize_formats (
- GAIL_TEXT_VIEW (streamable)->textutil->buffer,
- &n_mime_types);
- for (i = 0; i < n_mime_types; ++i)
- {
- if (!strcmp ("text/plain", mime_type) ||
- !strcmp (gdk_atom_name (atoms[i]), mime_type)) {
- GtkTextBuffer *buffer;
- guint8 *cbuf;
- GError *err = NULL;
- gsize len, written;
- gchar tname[80];
- GtkTextIter start, end;
- GIOChannel *gio = NULL;
- int fd;
- buffer = GAIL_TEXT_VIEW (streamable)->textutil->buffer;
- gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
- gtk_text_buffer_get_iter_at_offset (buffer, &end, -1);
- if (!strcmp ("text/plain", mime_type))
- {
- cbuf = (guint8*) gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- len = strlen ((const char *) cbuf);
- }
- else
- {
- cbuf = gtk_text_buffer_serialize (buffer, buffer, atoms[i], &start, &end, &len);
- }
- g_snprintf (tname, 20, "streamXXXXXX");
- fd = g_mkstemp (tname);
- gio = g_io_channel_unix_new (fd);
- g_io_channel_set_encoding (gio, NULL, &err);
- if (!err) g_io_channel_write_chars (gio, (const char *) cbuf, (gssize) len, &written, &err);
- else g_message ("%s", err->message);
- if (!err) g_io_channel_seek_position (gio, 0, G_SEEK_SET, &err);
- else g_message ("%s", err->message);
- if (!err) g_io_channel_flush (gio, &err);
- else g_message ("%s", err->message);
- if (err) {
- g_message ("<error writing to stream [%s]>", tname);
- g_error_free (err);
- }
- /* make sure the file is removed on unref of the giochannel */
- else {
- g_unlink (tname);
- return gio;
- }
- }
- }
- return NULL;
-}
-
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_TEXT_VIEW_H__
-#define __GAIL_TEXT_VIEW_H__
-
-#include "gailcontainer.h"
-#include <libgail-util/gailtextutil.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_TEXT_VIEW (gail_text_view_get_type ())
-#define GAIL_TEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TEXT_VIEW, GailTextView))
-#define GAIL_TEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TEXT_VIEW, GailTextViewClass))
-#define GAIL_IS_TEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TEXT_VIEW))
-#define GAIL_IS_TEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TEXT_VIEW))
-#define GAIL_TEXT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TEXT_VIEW, GailTextViewClass))
-
-typedef struct _GailTextView GailTextView;
-typedef struct _GailTextViewClass GailTextViewClass;
-
-struct _GailTextView
-{
- GailContainer parent;
-
- GailTextUtil *textutil;
- gint previous_insert_offset;
- gint previous_selection_bound;
- /*
- * These fields store information about text changed
- */
- gchar *signal_name;
- gint position;
- gint length;
-
- guint insert_notify_handler;
-};
-
-GType gail_text_view_get_type (void);
-
-struct _GailTextViewClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_TEXT_VIEW_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailtogglebutton.h"
-
-static void gail_toggle_button_class_init (GailToggleButtonClass *klass);
-
-static void gail_toggle_button_init (GailToggleButton *button);
-
-static void gail_toggle_button_toggled_gtk (GtkWidget *widget);
-
-static void gail_toggle_button_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-
-static void gail_toggle_button_real_initialize (AtkObject *obj,
- gpointer data);
-
-static AtkStateSet* gail_toggle_button_ref_state_set (AtkObject *accessible);
-
-G_DEFINE_TYPE (GailToggleButton, gail_toggle_button, GAIL_TYPE_BUTTON)
-
-static void
-gail_toggle_button_class_init (GailToggleButtonClass *klass)
-{
- GailWidgetClass *widget_class;
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- widget_class = (GailWidgetClass*)klass;
- widget_class->notify_gtk = gail_toggle_button_real_notify_gtk;
-
- class->ref_state_set = gail_toggle_button_ref_state_set;
- class->initialize = gail_toggle_button_real_initialize;
-}
-
-static void
-gail_toggle_button_init (GailToggleButton *button)
-{
-}
-
-static void
-gail_toggle_button_real_initialize (AtkObject *obj,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_toggle_button_parent_class)->initialize (obj, data);
-
- g_signal_connect (data,
- "toggled",
- G_CALLBACK (gail_toggle_button_toggled_gtk),
- NULL);
-
- if (GTK_IS_CHECK_BUTTON (data))
- obj->role = ATK_ROLE_CHECK_BOX;
- else
- obj->role = ATK_ROLE_TOGGLE_BUTTON;
-}
-
-static void
-gail_toggle_button_toggled_gtk (GtkWidget *widget)
-{
- AtkObject *accessible;
- GtkToggleButton *toggle_button;
-
- toggle_button = GTK_TOGGLE_BUTTON (widget);
-
- accessible = gtk_widget_get_accessible (widget);
- atk_object_notify_state_change (accessible, ATK_STATE_CHECKED,
- gtk_toggle_button_get_active (toggle_button));
-}
-
-static AtkStateSet*
-gail_toggle_button_ref_state_set (AtkObject *accessible)
-{
- AtkStateSet *state_set;
- GtkToggleButton *toggle_button;
- GtkWidget *widget;
-
- state_set = ATK_OBJECT_CLASS (gail_toggle_button_parent_class)->ref_state_set (accessible);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- return state_set;
-
- toggle_button = GTK_TOGGLE_BUTTON (widget);
-
- if (gtk_toggle_button_get_active (toggle_button))
- atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
-
- if (gtk_toggle_button_get_inconsistent (toggle_button))
- {
- atk_state_set_remove_state (state_set, ATK_STATE_ENABLED);
- atk_state_set_add_state (state_set, ATK_STATE_INDETERMINATE);
- }
-
- return state_set;
-}
-
-static void
-gail_toggle_button_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (obj);
- AtkObject *atk_obj;
- gboolean sensitive;
- gboolean inconsistent;
-
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (toggle_button));
- sensitive = gtk_widget_get_sensitive (GTK_WIDGET (toggle_button));
- inconsistent = gtk_toggle_button_get_inconsistent (toggle_button);
-
- if (strcmp (pspec->name, "inconsistent") == 0)
- {
- atk_object_notify_state_change (atk_obj, ATK_STATE_INDETERMINATE, inconsistent);
- atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
- }
- else if (strcmp (pspec->name, "sensitive") == 0)
- {
- /* Need to override gailwidget behavior of notifying for ENABLED */
- atk_object_notify_state_change (atk_obj, ATK_STATE_SENSITIVE, sensitive);
- atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
- }
- else
- GAIL_WIDGET_CLASS (gail_toggle_button_parent_class)->notify_gtk (obj, pspec);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_TOGGLE_BUTTON_H__
-#define __GAIL_TOGGLE_BUTTON_H__
-
-#include "gailbutton.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_TOGGLE_BUTTON (gail_toggle_button_get_type ())
-#define GAIL_TOGGLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TOGGLE_BUTTON, GailToggleButton))
-#define GAIL_TOGGLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TOGGLE_BUTTON, GailToggleButtonClass))
-#define GAIL_IS_TOGGLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TOGGLE_BUTTON))
-#define GAIL_IS_TOGGLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TOGGLE_BUTTON))
-#define GAIL_TOGGLE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TOGGLE_BUTTON, GailToggleButtonClass))
-
-typedef struct _GailToggleButton GailToggleButton;
-typedef struct _GailToggleButtonClass GailToggleButtonClass;
-
-struct _GailToggleButton
-{
- GailButton parent;
-};
-
-GType gail_toggle_button_get_type (void);
-
-struct _GailToggleButtonClass
-{
- GailButtonClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_TOGGLE_BUTTON_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <gtk/gtkx.h>
-
-#include "gailtoplevel.h"
-
-static void gail_toplevel_class_init (GailToplevelClass *klass);
-static void gail_toplevel_init (GailToplevel *toplevel);
-static void gail_toplevel_initialize (AtkObject *accessible,
- gpointer data);
-static void gail_toplevel_object_finalize (GObject *obj);
-
-/* atkobject.h */
-
-static gint gail_toplevel_get_n_children (AtkObject *obj);
-static AtkObject* gail_toplevel_ref_child (AtkObject *obj,
- gint i);
-static AtkObject* gail_toplevel_get_parent (AtkObject *obj);
-
-/* Callbacks */
-
-
-static void gail_toplevel_window_destroyed (GtkWindow *window,
- GailToplevel *text);
-static gboolean gail_toplevel_hide_event_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-static gboolean gail_toplevel_show_event_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-
-/* Misc */
-
-static void _gail_toplevel_remove_child (GailToplevel *toplevel,
- GtkWindow *window);
-static gboolean is_attached_menu_window (GtkWidget *widget);
-static gboolean is_combo_window (GtkWidget *widget);
-
-
-G_DEFINE_TYPE (GailToplevel, gail_toplevel, ATK_TYPE_OBJECT)
-
-static void
-gail_toplevel_class_init (GailToplevelClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS(klass);
- GObjectClass *g_object_class = G_OBJECT_CLASS(klass);
-
- class->initialize = gail_toplevel_initialize;
- class->get_n_children = gail_toplevel_get_n_children;
- class->ref_child = gail_toplevel_ref_child;
- class->get_parent = gail_toplevel_get_parent;
-
- g_object_class->finalize = gail_toplevel_object_finalize;
-}
-
-static void
-gail_toplevel_init (GailToplevel *toplevel)
-{
- GtkWindow *window;
- GtkWidget *widget;
- GList *l;
- guint signal_id;
-
- l = toplevel->window_list = gtk_window_list_toplevels ();
-
- while (l)
- {
- window = GTK_WINDOW (l->data);
- widget = GTK_WIDGET (window);
- if (!window ||
- !gtk_widget_get_visible (widget) ||
- is_attached_menu_window (widget) ||
-#ifdef GDK_WINDOWING_X11
- GTK_IS_PLUG (window) ||
-#endif
- gtk_widget_get_parent (GTK_WIDGET (window)))
- {
- GList *temp_l = l->next;
-
- toplevel->window_list = g_list_delete_link (toplevel->window_list, l);
- l = temp_l;
- }
- else
- {
- g_signal_connect (G_OBJECT (window),
- "destroy",
- G_CALLBACK (gail_toplevel_window_destroyed),
- toplevel);
- l = l->next;
- }
- }
-
- g_type_class_ref (GTK_TYPE_WINDOW);
-
- signal_id = g_signal_lookup ("show", GTK_TYPE_WINDOW);
- g_signal_add_emission_hook (signal_id, 0,
- gail_toplevel_show_event_watcher, toplevel, (GDestroyNotify) NULL);
-
- signal_id = g_signal_lookup ("hide", GTK_TYPE_WINDOW);
- g_signal_add_emission_hook (signal_id, 0,
- gail_toplevel_hide_event_watcher, toplevel, (GDestroyNotify) NULL);
-}
-
-static void
-gail_toplevel_initialize (AtkObject *accessible,
- gpointer data)
-{
- ATK_OBJECT_CLASS (gail_toplevel_parent_class)->initialize (accessible, data);
-
- accessible->role = ATK_ROLE_APPLICATION;
- accessible->name = g_get_prgname();
- accessible->accessible_parent = NULL;
-}
-
-static void
-gail_toplevel_object_finalize (GObject *obj)
-{
- GailToplevel *toplevel = GAIL_TOPLEVEL (obj);
-
- if (toplevel->window_list)
- g_list_free (toplevel->window_list);
-
- G_OBJECT_CLASS (gail_toplevel_parent_class)->finalize (obj);
-}
-
-static AtkObject*
-gail_toplevel_get_parent (AtkObject *obj)
-{
- return NULL;
-}
-
-static gint
-gail_toplevel_get_n_children (AtkObject *obj)
-{
- GailToplevel *toplevel = GAIL_TOPLEVEL (obj);
-
- gint rc = g_list_length (toplevel->window_list);
- return rc;
-}
-
-static AtkObject*
-gail_toplevel_ref_child (AtkObject *obj,
- gint i)
-{
- GailToplevel *toplevel;
- gpointer ptr;
- GtkWidget *widget;
- AtkObject *atk_obj;
-
- toplevel = GAIL_TOPLEVEL (obj);
- ptr = g_list_nth_data (toplevel->window_list, i);
- if (!ptr)
- return NULL;
- widget = GTK_WIDGET (ptr);
- atk_obj = gtk_widget_get_accessible (widget);
-
- g_object_ref (atk_obj);
- return atk_obj;
-}
-
-/*
- * Window destroy events on GtkWindow cause a child to be removed
- * from the toplevel
- */
-static void
-gail_toplevel_window_destroyed (GtkWindow *window,
- GailToplevel *toplevel)
-{
- _gail_toplevel_remove_child (toplevel, window);
-}
-
-/*
- * Show events cause a child to be added to the toplevel
- */
-static gboolean
-gail_toplevel_show_event_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GailToplevel *toplevel = GAIL_TOPLEVEL (data);
- AtkObject *atk_obj = ATK_OBJECT (toplevel);
- GObject *object;
- GtkWidget *widget;
- gint n_children;
- AtkObject *child;
-
- object = g_value_get_object (param_values + 0);
-
- if (!GTK_IS_WINDOW (object))
- return TRUE;
-
- widget = GTK_WIDGET (object);
- if (gtk_widget_get_parent (widget) ||
- is_attached_menu_window (widget) ||
-#ifdef GDK_WINDOWING_X11
- GTK_IS_PLUG (widget) ||
-#endif
- is_combo_window (widget))
- return TRUE;
-
- child = gtk_widget_get_accessible (widget);
- if (atk_object_get_role (child) == ATK_ROLE_REDUNDANT_OBJECT)
- {
- return TRUE;
- }
-
- /*
- * Add the window to the list & emit the signal.
- * Don't do this for tooltips (Bug #150649).
- */
- if (atk_object_get_role (child) == ATK_ROLE_TOOL_TIP)
- {
- return TRUE;
- }
-
- toplevel->window_list = g_list_append (toplevel->window_list, widget);
-
- n_children = g_list_length (toplevel->window_list);
-
- /*
- * Must subtract 1 from the n_children since the index is 0-based
- * but g_list_length is 1-based.
- */
- atk_object_set_parent (child, atk_obj);
- g_signal_emit_by_name (atk_obj, "children-changed::add",
- n_children - 1,
- child, NULL);
-
- /* Connect destroy signal callback */
- g_signal_connect (G_OBJECT(object),
- "destroy",
- G_CALLBACK (gail_toplevel_window_destroyed),
- toplevel);
-
- return TRUE;
-}
-
-/*
- * Hide events on GtkWindow cause a child to be removed from the toplevel
- */
-static gboolean
-gail_toplevel_hide_event_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GailToplevel *toplevel = GAIL_TOPLEVEL (data);
- GObject *object;
-
- object = g_value_get_object (param_values + 0);
-
- if (!GTK_IS_WINDOW (object))
- return TRUE;
-
- _gail_toplevel_remove_child (toplevel, GTK_WINDOW (object));
- return TRUE;
-}
-
-/*
- * Common code used by destroy and hide events on GtkWindow
- */
-static void
-_gail_toplevel_remove_child (GailToplevel *toplevel,
- GtkWindow *window)
-{
- AtkObject *atk_obj = ATK_OBJECT (toplevel);
- GList *l;
- guint window_count = 0;
- AtkObject *child;
-
- if (toplevel->window_list)
- {
- GtkWindow *tmp_window;
-
- /* Must loop through them all */
- for (l = toplevel->window_list; l; l = l->next)
- {
- tmp_window = GTK_WINDOW (l->data);
-
- if (window == tmp_window)
- {
- /* Remove the window from the window_list & emit the signal */
- toplevel->window_list = g_list_remove (toplevel->window_list,
- l->data);
- child = gtk_widget_get_accessible (GTK_WIDGET (window));
- g_signal_emit_by_name (atk_obj, "children-changed::remove",
- window_count,
- child, NULL);
- atk_object_set_parent (child, NULL);
- break;
- }
-
- window_count++;
- }
- }
-}
-
-static gboolean
-is_attached_menu_window (GtkWidget *widget)
-{
- GtkWidget *child;
- gboolean ret = FALSE;
-
- child = gtk_bin_get_child (GTK_BIN (widget));
- if (GTK_IS_MENU (child))
- {
- GtkWidget *attach;
-
- attach = gtk_menu_get_attach_widget (GTK_MENU (child));
- /* Allow for menu belonging to the Panel Menu, which is a GtkButton */
- if (GTK_IS_MENU_ITEM (attach) ||
- GTK_IS_BUTTON (attach))
- ret = TRUE;
- }
- return ret;
-}
-
-static gboolean
-is_combo_window (GtkWidget *widget)
-{
- GtkWidget *child;
- AtkObject *obj;
-
- child = gtk_bin_get_child (GTK_BIN (widget));
-
- if (!GTK_IS_EVENT_BOX (child))
- return FALSE;
-
- child = gtk_bin_get_child (GTK_BIN (child));
-
- if (!GTK_IS_FRAME (child))
- return FALSE;
-
- child = gtk_bin_get_child (GTK_BIN (child));
-
- if (!GTK_IS_SCROLLED_WINDOW (child))
- return FALSE;
-
- obj = gtk_widget_get_accessible (child);
- obj = atk_object_get_parent (obj);
-
- return FALSE;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_TOPLEVEL_H__
-#define __GAIL_TOPLEVEL_H__
-
-#include <atk/atk.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_TOPLEVEL (gail_toplevel_get_type ())
-#define GAIL_TOPLEVEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TOPLEVEL, GailToplevel))
-#define GAIL_TOPLEVEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TOPLEVEL, GailToplevelClass))
-#define GAIL_IS_TOPLEVEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TOPLEVEL))
-#define GAIL_IS_TOPLEVEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TOPLEVEL))
-#define GAIL_TOPLEVEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TOPLEVEL, GailToplevelClass))
-
-typedef struct _GailToplevel GailToplevel;
-typedef struct _GailToplevelClass GailToplevelClass;
-
-struct _GailToplevel
-{
- AtkObject parent;
- GList *window_list;
-};
-
-GType gail_toplevel_get_type (void);
-
-struct _GailToplevelClass
-{
- AtkObjectClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_TOPLEVEL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <gtk/gtk.h>
-#ifdef GDK_WINDOWING_X11
-#include <gdk/x11/gdkx.h>
-#endif
-#include "gailtreeview.h"
-#include "gailrenderercell.h"
-#include "gailbooleancell.h"
-#include "gailcontainercell.h"
-#include "gailtextcell.h"
-#include "gailcellparent.h"
-#include "gail-private-macros.h"
-
-typedef struct _GailTreeViewRowInfo GailTreeViewRowInfo;
-typedef struct _GailTreeViewCellInfo GailTreeViewCellInfo;
-
-static void gail_tree_view_class_init (GailTreeViewClass *klass);
-static void gail_tree_view_init (GailTreeView *view);
-static void gail_tree_view_real_initialize (AtkObject *obj,
- gpointer data);
-static void gail_tree_view_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-static void gail_tree_view_finalize (GObject *object);
-
-static void gail_tree_view_connect_widget_destroyed
- (GtkAccessible *accessible);
-static void gail_tree_view_destroyed (GtkWidget *widget,
- GtkAccessible *accessible);
-/* atkobject.h */
-
-static gint gail_tree_view_get_n_children (AtkObject *obj);
-static AtkObject* gail_tree_view_ref_child (AtkObject *obj,
- gint i);
-static AtkStateSet* gail_tree_view_ref_state_set (AtkObject *obj);
-
-/* atkcomponent.h */
-
-static void atk_component_interface_init (AtkComponentIface *iface);
-
-static AtkObject* gail_tree_view_ref_accessible_at_point
- (AtkComponent *component,
- gint x,
- gint y,
- AtkCoordType coord_type);
-
-/* atktable.h */
-
-static void atk_table_interface_init (AtkTableIface *iface);
-
-static gint gail_tree_view_get_index_at (AtkTable *table,
- gint row,
- gint column);
-static gint gail_tree_view_get_column_at_index
- (AtkTable *table,
- gint index);
-static gint gail_tree_view_get_row_at_index (AtkTable *table,
- gint index);
-
-static AtkObject* gail_tree_view_table_ref_at (AtkTable *table,
- gint row,
- gint column);
-static gint gail_tree_view_get_n_rows (AtkTable *table);
-static gint gail_tree_view_get_n_columns (AtkTable *table);
-static gint get_n_actual_columns (GtkTreeView *tree_view);
-static gboolean gail_tree_view_is_row_selected (AtkTable *table,
- gint row);
-static gboolean gail_tree_view_is_selected (AtkTable *table,
- gint row,
- gint column);
-static gint gail_tree_view_get_selected_rows
- (AtkTable *table,
- gint **selected);
-static gboolean gail_tree_view_add_row_selection
- (AtkTable *table,
- gint row);
-static gboolean gail_tree_view_remove_row_selection
- (AtkTable *table,
- gint row);
-static AtkObject* gail_tree_view_get_row_header (AtkTable *table,
- gint row);
-static AtkObject* gail_tree_view_get_column_header
- (AtkTable *table,
- gint column);
-static void gail_tree_view_set_row_header (AtkTable *table,
- gint row,
- AtkObject *header);
-static void gail_tree_view_set_column_header
- (AtkTable *table,
- gint column,
- AtkObject *header);
-static AtkObject*
- gail_tree_view_get_caption (AtkTable *table);
-static void gail_tree_view_set_caption (AtkTable *table,
- AtkObject *caption);
-static AtkObject* gail_tree_view_get_summary (AtkTable *table);
-static void gail_tree_view_set_summary (AtkTable *table,
- AtkObject *accessible);
-static const gchar*
- gail_tree_view_get_row_description
- (AtkTable *table,
- gint row);
-static void gail_tree_view_set_row_description
- (AtkTable *table,
- gint row,
- const gchar *description);
-static const gchar*
- gail_tree_view_get_column_description
- (AtkTable *table,
- gint column);
-static void gail_tree_view_set_column_description
- (AtkTable *table,
- gint column,
- const gchar *description);
-
-static void set_row_data (AtkTable *table,
- gint row,
- AtkObject *header,
- const gchar *description,
- gboolean is_header);
-static GailTreeViewRowInfo*
- get_row_info (AtkTable *table,
- gint row);
-
-/* atkselection.h */
-
-static void atk_selection_interface_init (AtkSelectionIface *iface);
-static gboolean gail_tree_view_add_selection (AtkSelection *selection,
- gint i);
-static gboolean gail_tree_view_clear_selection (AtkSelection *selection);
-static AtkObject* gail_tree_view_ref_selection (AtkSelection *selection,
- gint i);
-static gint gail_tree_view_get_selection_count
- (AtkSelection *selection);
-static gboolean gail_tree_view_is_child_selected
- (AtkSelection *selection,
- gint i);
-
-/* gailcellparent.h */
-
-static void gail_cell_parent_interface_init (GailCellParentIface *iface);
-static void gail_tree_view_get_cell_extents (GailCellParent *parent,
- GailCell *cell,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type);
-static void gail_tree_view_get_cell_area (GailCellParent *parent,
- GailCell *cell,
- GdkRectangle *cell_rect);
-static gboolean gail_tree_view_grab_cell_focus (GailCellParent *parent,
- GailCell *cell);
-
-/* signal handling */
-
-static gboolean gail_tree_view_expand_row_gtk (GtkTreeView *tree_view,
- GtkTreeIter *iter,
- GtkTreePath *path);
-static gint idle_expand_row (gpointer data);
-static gboolean gail_tree_view_collapse_row_gtk (GtkTreeView *tree_view,
- GtkTreeIter *iter,
- GtkTreePath *path);
-static void gail_tree_view_size_allocate_gtk (GtkWidget *widget,
- GtkAllocation *allocation);
-static void gail_tree_view_changed_gtk (GtkTreeSelection *selection,
- gpointer data);
-
-static void columns_changed (GtkTreeView *tree_view);
-static void cursor_changed (GtkTreeView *tree_view);
-static gint idle_cursor_changed (gpointer data);
-static gboolean focus_in (GtkWidget *widget);
-static gboolean focus_out (GtkWidget *widget);
-
-static void model_row_changed (GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer user_data);
-static void column_visibility_changed (GObject *object,
- GParamSpec *param,
- gpointer user_data);
-static void model_row_inserted (GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer user_data);
-static void model_row_deleted (GtkTreeModel *tree_model,
- GtkTreePath *path,
- gpointer user_data);
-static void destroy_count_func (GtkTreeView *tree_view,
- GtkTreePath *path,
- gint count,
- gpointer user_data);
-static void model_rows_reordered (GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gint *new_order,
- gpointer user_data);
-static void adjustment_changed (GtkAdjustment *adjustment,
- GtkTreeView *tree_view);
-
-/* Misc */
-
-static void set_iter_nth_row (GtkTreeView *tree_view,
- GtkTreeIter *iter,
- gint row);
-static gint get_row_from_tree_path (GtkTreeView *tree_view,
- GtkTreePath *path);
-static GtkTreeViewColumn* get_column (GtkTreeView *tree_view,
- gint in_col);
-static gint get_actual_column_number (GtkTreeView *tree_view,
- gint visible_column);
-static gint get_visible_column_number (GtkTreeView *tree_view,
- gint actual_column);
-static void iterate_thru_children (GtkTreeView *tree_view,
- GtkTreeModel *tree_model,
- GtkTreePath *tree_path,
- GtkTreePath *orig,
- gint *count,
- gint depth);
-static GtkTreeIter* return_iter_nth_row (GtkTreeView *tree_view,
- GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gint increment,
- gint row);
-static void free_row_info (GArray *array,
- gint array_idx,
- gboolean shift);
-static void clean_cell_info (GailTreeView *tree_view,
- GList *list);
-static void clean_rows (GailTreeView *tree_view);
-static void clean_cols (GailTreeView *tree_view,
- GtkTreeViewColumn *tv_col);
-static void traverse_cells (GailTreeView *tree_view,
- GtkTreePath *tree_path,
- gboolean set_stale,
- gboolean inc_row);
-static gboolean update_cell_value (GailRendererCell *renderer_cell,
- GailTreeView *gailview,
- gboolean emit_change_signal);
-static void set_cell_visibility (GtkTreeView *tree_view,
- GailCell *cell,
- GtkTreeViewColumn *tv_col,
- GtkTreePath *tree_path,
- gboolean emit_signal);
-static gboolean is_cell_showing (GtkTreeView *tree_view,
- GdkRectangle *cell_rect);
-static void set_expand_state (GtkTreeView *tree_view,
- GtkTreeModel *tree_model,
- GailTreeView *gailview,
- GtkTreePath *tree_path,
- gboolean set_on_ancestor);
-static void add_cell_actions (GailCell *cell,
- gboolean editable);
-
-static void toggle_cell_expanded (GailCell *cell);
-static void toggle_cell_toggled (GailCell *cell);
-static void edit_cell (GailCell *cell);
-static void activate_cell (GailCell *cell);
-static void cell_destroyed (gpointer data);
-#if 0
-static void cell_info_remove (GailTreeView *tree_view,
- GailCell *cell);
-#endif
-static void cell_info_get_index (GtkTreeView *tree_view,
- GailTreeViewCellInfo *info,
- gint *index);
-static void cell_info_new (GailTreeView *gailview,
- GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeViewColumn *tv_col,
- GailCell *cell);
-static GailCell* find_cell (GailTreeView *gailview,
- gint index);
-static void refresh_cell_index (GailCell *cell);
-static void get_selected_rows (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data);
-static void connect_model_signals (GtkTreeView *view,
- GailTreeView *gailview);
-static void disconnect_model_signals (GailTreeView *gailview);
-static void clear_cached_data (GailTreeView *view);
-static gint get_column_number (GtkTreeView *tree_view,
- GtkTreeViewColumn *column,
- gboolean visible);
-static gint get_focus_index (GtkTreeView *tree_view);
-static gint get_index (GtkTreeView *tree_view,
- GtkTreePath *path,
- gint actual_column);
-static void count_rows (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreePath *end_path,
- gint *count,
- gint level,
- gint depth);
-
-static gboolean get_next_node_with_child_at_depth
- (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreePath **path,
- gint level,
- gint depth);
-static gboolean get_next_node_with_child (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreePath **return_path);
-static gboolean get_tree_path_from_row_index (GtkTreeModel *model,
- gint row_index,
- GtkTreePath **tree_path);
-static gint get_row_count (GtkTreeModel *model);
-static gboolean get_path_column_from_index (GtkTreeView *tree_view,
- gint index,
- GtkTreePath **path,
- GtkTreeViewColumn **column);
-static void set_cell_expandable (GailCell *cell);
-
-static GailTreeViewCellInfo* find_cell_info (GailTreeView *view,
- GailCell *cell,
- GList** list,
- gboolean live_only);
-static AtkObject * get_header_from_column (GtkTreeViewColumn *tv_col);
-static gboolean idle_garbage_collect_cell_data (gpointer data);
-static gboolean garbage_collect_cell_data (gpointer data);
-
-static GQuark quark_column_desc_object = 0;
-static GQuark quark_column_header_object = 0;
-static gboolean editing = FALSE;
-
-struct _GailTreeViewRowInfo
-{
- GtkTreeRowReference *row_ref;
- gchar *description;
- AtkObject *header;
-};
-
-struct _GailTreeViewCellInfo
-{
- GailCell *cell;
- GtkTreeRowReference *cell_row_ref;
- GtkTreeViewColumn *cell_col_ref;
- GailTreeView *view;
- gboolean in_use;
-};
-
-G_DEFINE_TYPE_WITH_CODE (GailTreeView, gail_tree_view, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_TABLE, atk_table_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init)
- G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)
- G_IMPLEMENT_INTERFACE (GAIL_TYPE_CELL_PARENT, gail_cell_parent_interface_init))
-
-static void
-gail_tree_view_class_init (GailTreeViewClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkAccessibleClass *accessible_class;
- GailWidgetClass *widget_class;
- GailContainerClass *container_class;
-
- accessible_class = (GtkAccessibleClass*)klass;
- widget_class = (GailWidgetClass*)klass;
- container_class = (GailContainerClass*)klass;
-
- class->get_n_children = gail_tree_view_get_n_children;
- class->ref_child = gail_tree_view_ref_child;
- class->ref_state_set = gail_tree_view_ref_state_set;
- class->initialize = gail_tree_view_real_initialize;
-
- widget_class->notify_gtk = gail_tree_view_real_notify_gtk;
-
- accessible_class->connect_widget_destroyed = gail_tree_view_connect_widget_destroyed;
-
- /*
- * The children of a GtkTreeView are the buttons at the top of the columns
- * we do not represent these as children so we do not want to report
- * children added or deleted when these changed.
- */
- container_class->add_gtk = NULL;
- container_class->remove_gtk = NULL;
-
- gobject_class->finalize = gail_tree_view_finalize;
-
- quark_column_desc_object = g_quark_from_static_string ("gtk-column-object");
- quark_column_header_object = g_quark_from_static_string ("gtk-header-object");
-}
-
-static void
-gail_tree_view_init (GailTreeView *view)
-{
-}
-
-static void
-gail_tree_view_hadjustment_set (GObject *widget,
- GParamSpec *pspec,
- gpointer data)
-{
- GtkAdjustment *adj;
- GailTreeView *view = data;
-
- g_object_get (widget, "hadjustment", &adj, NULL);
- view->old_hadj = adj;
- g_object_add_weak_pointer (G_OBJECT (view->old_hadj), (gpointer *)&view->old_hadj);
- g_signal_connect (adj,
- "value-changed",
- G_CALLBACK (adjustment_changed),
- widget);
-}
-
-static void
-gail_tree_view_vadjustment_set (GObject *widget,
- GParamSpec *pspec,
- gpointer data)
-{
- GtkAdjustment *adj;
- GailTreeView *view = data;
-
- g_object_get (widget, "vadjustment", &adj, NULL);
- view->old_vadj = adj;
- g_object_add_weak_pointer (G_OBJECT (view->old_vadj), (gpointer *)&view->old_vadj);
- g_signal_connect (adj,
- "value-changed",
- G_CALLBACK (adjustment_changed),
- widget);
-}
-
-static void
-gail_tree_view_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GailTreeView *view;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
- GList *tv_cols, *tmp_list;
- GtkWidget *widget;
-
- ATK_OBJECT_CLASS (gail_tree_view_parent_class)->initialize (obj, data);
-
- view = GAIL_TREE_VIEW (obj);
- view->caption = NULL;
- view->summary = NULL;
- view->row_data = NULL;
- view->col_data = NULL;
- view->cell_data = NULL;
- view->focus_cell = NULL;
- view->old_hadj = NULL;
- view->old_vadj = NULL;
- view->idle_expand_id = 0;
- view->idle_expand_path = NULL;
-
- view->n_children_deleted = 0;
-
- widget = GTK_WIDGET (data);
- g_signal_connect_after (widget,
- "row-collapsed",
- G_CALLBACK (gail_tree_view_collapse_row_gtk),
- NULL);
- g_signal_connect (widget,
- "row-expanded",
- G_CALLBACK (gail_tree_view_expand_row_gtk),
- NULL);
- g_signal_connect (widget,
- "size-allocate",
- G_CALLBACK (gail_tree_view_size_allocate_gtk),
- NULL);
-
- tree_view = GTK_TREE_VIEW (widget);
- tree_model = gtk_tree_view_get_model (tree_view);
-
- /* Set up signal handling */
-
- g_signal_connect_data (gtk_tree_view_get_selection (tree_view),
- "changed",
- (GCallback) gail_tree_view_changed_gtk,
- obj, NULL, 0);
-
- g_signal_connect_data (tree_view, "columns-changed",
- (GCallback) columns_changed, NULL, NULL, 0);
- g_signal_connect_data (tree_view, "cursor-changed",
- (GCallback) cursor_changed, NULL, NULL, 0);
- g_signal_connect_data (GTK_WIDGET (tree_view), "focus-in-event",
- (GCallback) focus_in, NULL, NULL, 0);
- g_signal_connect_data (GTK_WIDGET (tree_view), "focus-out-event",
- (GCallback) focus_out, NULL, NULL, 0);
-
- view->tree_model = tree_model;
- if (tree_model)
- {
- g_object_add_weak_pointer (G_OBJECT (view->tree_model), (gpointer *)&view->tree_model);
- connect_model_signals (tree_view, view);
-
- if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
- obj->role = ATK_ROLE_TABLE;
- else
- obj->role = ATK_ROLE_TREE_TABLE;
- }
- else
- {
- obj->role = ATK_ROLE_UNKNOWN;
- }
-
- /* adjustment callbacks */
-
- gail_tree_view_hadjustment_set (G_OBJECT (widget), NULL, view);
- gail_tree_view_vadjustment_set (G_OBJECT (widget), NULL, view);
- g_signal_connect (widget,
- "notify::hadjustment",
- G_CALLBACK (gail_tree_view_hadjustment_set),
- view);
- g_signal_connect (widget,
- "notify::vadjustment",
- G_CALLBACK (gail_tree_view_vadjustment_set),
- view);
-
- view->col_data = g_array_sized_new (FALSE, TRUE,
- sizeof(GtkTreeViewColumn *), 0);
-
- tv_cols = gtk_tree_view_get_columns (tree_view);
-
- for (tmp_list = tv_cols; tmp_list; tmp_list = tmp_list->next)
- {
- g_signal_connect_data (tmp_list->data, "notify::visible",
- (GCallback)column_visibility_changed,
- tree_view, NULL, FALSE);
- g_array_append_val (view->col_data, tmp_list->data);
- }
-
- gtk_tree_view_set_destroy_count_func (tree_view,
- destroy_count_func,
- NULL, NULL);
- g_list_free (tv_cols);
-}
-
-static void
-gail_tree_view_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkWidget *widget;
- AtkObject* atk_obj;
- GtkTreeView *tree_view;
- GailTreeView *gailview;
- GtkAdjustment *adj;
-
- widget = GTK_WIDGET (obj);
- atk_obj = gtk_widget_get_accessible (widget);
- tree_view = GTK_TREE_VIEW (widget);
- gailview = GAIL_TREE_VIEW (atk_obj);
-
- if (strcmp (pspec->name, "model") == 0)
- {
- GtkTreeModel *tree_model;
- AtkRole role;
-
- tree_model = gtk_tree_view_get_model (tree_view);
- if (gailview->tree_model)
- disconnect_model_signals (gailview);
- clear_cached_data (gailview);
- gailview->tree_model = tree_model;
- /*
- * if there is no model the GtkTreeView is probably being destroyed
- */
- if (tree_model)
- {
- g_object_add_weak_pointer (G_OBJECT (gailview->tree_model), (gpointer *)&gailview->tree_model);
- connect_model_signals (tree_view, gailview);
-
- if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
- role = ATK_ROLE_TABLE;
- else
- role = ATK_ROLE_TREE_TABLE;
- }
- else
- {
- role = ATK_ROLE_UNKNOWN;
- }
- atk_object_set_role (atk_obj, role);
- g_object_freeze_notify (G_OBJECT (atk_obj));
- g_signal_emit_by_name (atk_obj, "model_changed");
- g_signal_emit_by_name (atk_obj, "visible_data_changed");
- g_object_thaw_notify (G_OBJECT (atk_obj));
- }
- else if (strcmp (pspec->name, "hadjustment") == 0)
- {
- g_object_get (tree_view, "hadjustment", &adj, NULL);
- g_signal_handlers_disconnect_by_func (gailview->old_hadj,
- (gpointer) adjustment_changed,
- widget);
- gailview->old_hadj = adj;
- g_object_add_weak_pointer (G_OBJECT (gailview->old_hadj), (gpointer *)&gailview->old_hadj);
- g_signal_connect (adj,
- "value-changed",
- G_CALLBACK (adjustment_changed),
- tree_view);
- }
- else if (strcmp (pspec->name, "vadjustment") == 0)
- {
- g_object_get (tree_view, "vadjustment", &adj, NULL);
- g_signal_handlers_disconnect_by_func (gailview->old_vadj,
- (gpointer) adjustment_changed,
- widget);
- gailview->old_vadj = adj;
- g_object_add_weak_pointer (G_OBJECT (gailview->old_hadj), (gpointer *)&gailview->old_vadj);
- g_signal_connect (adj,
- "value-changed",
- G_CALLBACK (adjustment_changed),
- tree_view);
- }
- else
- GAIL_WIDGET_CLASS (gail_tree_view_parent_class)->notify_gtk (obj, pspec);
-}
-
-static void
-gail_tree_view_finalize (GObject *object)
-{
- GailTreeView *view = GAIL_TREE_VIEW (object);
-
- clear_cached_data (view);
-
- /* remove any idle handlers still pending */
- if (view->idle_garbage_collect_id)
- g_source_remove (view->idle_garbage_collect_id);
- if (view->idle_cursor_changed_id)
- g_source_remove (view->idle_cursor_changed_id);
- if (view->idle_expand_id)
- g_source_remove (view->idle_expand_id);
-
- if (view->caption)
- g_object_unref (view->caption);
- if (view->summary)
- g_object_unref (view->summary);
-
- if (view->tree_model)
- disconnect_model_signals (view);
-
- if (view->col_data)
- {
- GArray *array = view->col_data;
-
- /*
- * No need to free the contents of the array since it
- * just contains pointers to the GtkTreeViewColumn
- * objects that are in the GtkTreeView.
- */
- g_array_free (array, TRUE);
- }
-
- G_OBJECT_CLASS (gail_tree_view_parent_class)->finalize (object);
-}
-
-static void
-gail_tree_view_connect_widget_destroyed (GtkAccessible *accessible)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- if (widget)
- {
- g_signal_connect_after (widget,
- "destroy",
- G_CALLBACK (gail_tree_view_destroyed),
- accessible);
- }
- GTK_ACCESSIBLE_CLASS (gail_tree_view_parent_class)->connect_widget_destroyed (accessible);
-}
-
-static void
-gail_tree_view_destroyed (GtkWidget *widget,
- GtkAccessible *accessible)
-{
- GtkAdjustment *adj;
- GailTreeView *gailview;
-
- gail_return_if_fail (GTK_IS_TREE_VIEW (widget));
-
- gailview = GAIL_TREE_VIEW (accessible);
- adj = gailview->old_hadj;
- if (adj)
- g_signal_handlers_disconnect_by_func (adj,
- (gpointer) adjustment_changed,
- widget);
- adj = gailview->old_vadj;
- if (adj)
- g_signal_handlers_disconnect_by_func (adj,
- (gpointer) adjustment_changed,
- widget);
- if (gailview->tree_model)
- {
- disconnect_model_signals (gailview);
- gailview->tree_model = NULL;
- }
- if (gailview->focus_cell)
- {
- g_object_unref (gailview->focus_cell);
- gailview->focus_cell = NULL;
- }
- if (gailview->idle_expand_id)
- {
- g_source_remove (gailview->idle_expand_id);
- gailview->idle_expand_id = 0;
- }
-}
-
-gint
-get_focus_index (GtkTreeView *tree_view)
-{
- GtkTreePath *focus_path;
- GtkTreeViewColumn *focus_column;
- gint index;
-
- gtk_tree_view_get_cursor (tree_view, &focus_path, &focus_column);
- if (focus_path && focus_column)
- {
-
- index = get_index (tree_view, focus_path,
- get_column_number (tree_view, focus_column, FALSE));
- }
- else
- index = -1;
-
- if (focus_path)
- gtk_tree_path_free (focus_path);
-
- return index;
-}
-
-AtkObject *
-gail_tree_view_ref_focus_cell (GtkTreeView *tree_view)
-{
- /*
- * This function returns a reference to the accessible object for the cell
- * in the treeview which has focus, if a cell has focus.
- */
- AtkObject *focus_cell = NULL;
- AtkObject *atk_obj;
- gint focus_index;
-
- focus_index = get_focus_index (tree_view);
- if (focus_index >= 0)
- {
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
- focus_cell = atk_object_ref_accessible_child (atk_obj, focus_index);
- }
-
- return focus_cell;
-}
-
-/* atkobject.h */
-
-static gint
-gail_tree_view_get_n_children (AtkObject *obj)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
- gint n_rows, n_cols;
-
- gail_return_val_if_fail (GAIL_IS_TREE_VIEW (obj), 0);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return 0;
-
- tree_view = GTK_TREE_VIEW (widget);
- tree_model = gtk_tree_view_get_model (tree_view);
-
- /*
- * We get the total number of rows including those which are collapsed
- */
- n_rows = get_row_count (tree_model);
- /*
- * We get the total number of columns including those which are not visible
- */
- n_cols = get_n_actual_columns (tree_view);
- return (n_rows * n_cols);
-}
-
-static AtkObject*
-gail_tree_view_ref_child (AtkObject *obj,
- gint i)
-{
- GtkWidget *widget;
- GailTreeView *gailview;
- GailCell *cell;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
- GtkCellRenderer *renderer;
- GtkTreeIter iter;
- GtkTreeViewColumn *tv_col;
- GtkTreeSelection *selection;
- GtkTreePath *path;
- AtkRegistry *default_registry;
- AtkObjectFactory *factory;
- AtkObject *child;
- AtkObject *parent;
- GtkTreeViewColumn *expander_tv;
- GList *renderer_list;
- GList *l;
- GailContainerCell *container = NULL;
- GailRendererCell *renderer_cell;
- gboolean is_expander, is_expanded, retval;
- gboolean editable = FALSE;
- gint focus_index;
-
- g_return_val_if_fail (GAIL_IS_TREE_VIEW (obj), NULL);
- g_return_val_if_fail (i >= 0, NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- if (i >= gail_tree_view_get_n_children (obj))
- return NULL;
-
- tree_view = GTK_TREE_VIEW (widget);
- if (i < get_n_actual_columns (tree_view))
- {
- tv_col = gtk_tree_view_get_column (tree_view, i);
- child = get_header_from_column (tv_col);
- if (child)
- g_object_ref (child);
- return child;
- }
-
- gailview = GAIL_TREE_VIEW (obj);
- /*
- * Check whether the child is cached
- */
- cell = find_cell (gailview, i);
- if (cell)
- {
- g_object_ref (cell);
- return ATK_OBJECT (cell);
- }
-
- if (gailview->focus_cell == NULL)
- focus_index = get_focus_index (tree_view);
- else
- focus_index = -1;
- /*
- * Find the TreePath and GtkTreeViewColumn for the index
- */
- if (!get_path_column_from_index (tree_view, i, &path, &tv_col))
- return NULL;
-
- tree_model = gtk_tree_view_get_model (tree_view);
- retval = gtk_tree_model_get_iter (tree_model, &iter, path);
- gail_return_val_if_fail (retval, NULL);
-
- expander_tv = gtk_tree_view_get_expander_column (tree_view);
- is_expander = FALSE;
- is_expanded = FALSE;
- if (gtk_tree_model_iter_has_child (tree_model, &iter))
- {
- if (expander_tv == tv_col)
- {
- is_expander = TRUE;
- is_expanded = gtk_tree_view_row_expanded (tree_view, path);
- }
- }
- gtk_tree_view_column_cell_set_cell_data (tv_col, tree_model, &iter,
- is_expander, is_expanded);
-
- renderer_list = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tv_col));
-
- /* If there are more than one renderer in the list, make a container */
-
- if (renderer_list && renderer_list->next)
- {
- GailCell *container_cell;
-
- container = gail_container_cell_new ();
- gail_return_val_if_fail (container, NULL);
-
- container_cell = GAIL_CELL (container);
- gail_cell_initialise (container_cell,
- widget, ATK_OBJECT (gailview),
- i);
- /*
- * The GailTreeViewCellInfo structure for the container will be before
- * the ones for the cells so that the first one we find for a position
- * will be for the container
- */
- cell_info_new (gailview, tree_model, path, tv_col, container_cell);
- container_cell->refresh_index = refresh_cell_index;
- parent = ATK_OBJECT (container);
- }
- else
- parent = ATK_OBJECT (gailview);
-
- child = NULL;
-
- /*
- * Now we make a fake cell_renderer if there is no cell in renderer_list
- */
-
- if (renderer_list == NULL)
- {
- GtkCellRenderer *fake_renderer;
- fake_renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT, NULL);
- default_registry = atk_get_default_registry ();
- factory = atk_registry_get_factory (default_registry,
- G_OBJECT_TYPE (fake_renderer));
- child = atk_object_factory_create_accessible (factory,
- G_OBJECT (fake_renderer));
- gail_return_val_if_fail (GAIL_IS_RENDERER_CELL (child), NULL);
- cell = GAIL_CELL (child);
- renderer_cell = GAIL_RENDERER_CELL (child);
- renderer_cell->renderer = fake_renderer;
-
- /* Create the GailTreeViewCellInfo structure for this cell */
- cell_info_new (gailview, tree_model, path, tv_col, cell);
-
- gail_cell_initialise (cell,
- widget, parent,
- i);
-
- cell->refresh_index = refresh_cell_index;
-
- /* set state if it is expandable */
- if (is_expander)
- {
- set_cell_expandable (cell);
- if (is_expanded)
- gail_cell_add_state (cell,
- ATK_STATE_EXPANDED,
- FALSE);
- }
- } else {
- for (l = renderer_list; l; l = l->next)
- {
- renderer = GTK_CELL_RENDERER (l->data);
-
- if (GTK_IS_CELL_RENDERER_TEXT (renderer))
- g_object_get (G_OBJECT (renderer), "editable", &editable, NULL);
-
- default_registry = atk_get_default_registry ();
- factory = atk_registry_get_factory (default_registry,
- G_OBJECT_TYPE (renderer));
- child = atk_object_factory_create_accessible (factory,
- G_OBJECT (renderer));
- gail_return_val_if_fail (GAIL_IS_RENDERER_CELL (child), NULL);
- cell = GAIL_CELL (child);
- renderer_cell = GAIL_RENDERER_CELL (child);
-
- /* Create the GailTreeViewCellInfo structure for this cell */
- cell_info_new (gailview, tree_model, path, tv_col, cell);
-
- gail_cell_initialise (cell,
- widget, parent,
- i);
-
- if (container)
- gail_container_cell_add_child (container, cell);
- else
- cell->refresh_index = refresh_cell_index;
-
- update_cell_value (renderer_cell, gailview, FALSE);
- /* Add the actions appropriate for this cell */
- add_cell_actions (cell, editable);
-
- /* set state if it is expandable */
- if (is_expander)
- {
- set_cell_expandable (cell);
- if (is_expanded)
- gail_cell_add_state (cell,
- ATK_STATE_EXPANDED,
- FALSE);
- }
- /*
- * If the column is visible, sets the cell's state
- */
- if (gtk_tree_view_column_get_visible (tv_col))
- set_cell_visibility (tree_view, cell, tv_col, path, FALSE);
- /*
- * If the row is selected, all cells on the row are selected
- */
- selection = gtk_tree_view_get_selection (tree_view);
-
- if (gtk_tree_selection_path_is_selected (selection, path))
- gail_cell_add_state (cell, ATK_STATE_SELECTED, FALSE);
-
- gail_cell_add_state (cell, ATK_STATE_FOCUSABLE, FALSE);
- if (focus_index == i)
- {
- gailview->focus_cell = g_object_ref (cell);
- gail_cell_add_state (cell, ATK_STATE_FOCUSED, FALSE);
- g_signal_emit_by_name (gailview,
- "active-descendant-changed",
- cell);
- }
- }
- g_list_free (renderer_list);
- if (container)
- child = ATK_OBJECT (container);
- }
-
- if (expander_tv == tv_col)
- {
- AtkRelationSet *relation_set;
- AtkObject *accessible_array[1];
- AtkRelation* relation;
- AtkObject *parent_node;
-
- relation_set = atk_object_ref_relation_set (ATK_OBJECT (child));
-
- gtk_tree_path_up (path);
- if (gtk_tree_path_get_depth (path) == 0)
- parent_node = obj;
- else
- {
- gint parent_index;
- gint n_columns;
-
- n_columns = get_n_actual_columns (tree_view);
- parent_index = get_index (tree_view, path, i % n_columns);
- parent_node = atk_object_ref_accessible_child (obj, parent_index);
- }
- accessible_array[0] = parent_node;
- relation = atk_relation_new (accessible_array, 1,
- ATK_RELATION_NODE_CHILD_OF);
- atk_relation_set_add (relation_set, relation);
- atk_object_add_relationship (parent_node, ATK_RELATION_NODE_PARENT_OF,
- child);
- g_object_unref (relation);
- g_object_unref (relation_set);
- }
- gtk_tree_path_free (path);
-
- /*
- * We do not increase the reference count here; when g_object_unref() is
- * called for the cell then cell_destroyed() is called and
- * this removes the cell from the cache.
- */
- return child;
-}
-
-static AtkStateSet*
-gail_tree_view_ref_state_set (AtkObject *obj)
-{
- AtkStateSet *state_set;
- GtkWidget *widget;
-
- state_set = ATK_OBJECT_CLASS (gail_tree_view_parent_class)->ref_state_set (obj);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
-
- if (widget != NULL)
- atk_state_set_add_state (state_set, ATK_STATE_MANAGES_DESCENDANTS);
-
- return state_set;
-}
-
-/* atkcomponent.h */
-
-static void
-atk_component_interface_init (AtkComponentIface *iface)
-{
- iface->ref_accessible_at_point = gail_tree_view_ref_accessible_at_point;
-}
-
-static AtkObject*
-gail_tree_view_ref_accessible_at_point (AtkComponent *component,
- gint x,
- gint y,
- AtkCoordType coord_type)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreePath *path;
- GtkTreeViewColumn *tv_column;
- gint x_pos, y_pos;
- gint bx, by;
- gboolean ret_val;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- tree_view = GTK_TREE_VIEW (widget);
-
- atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type);
- gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, &bx, &by);
- ret_val = gtk_tree_view_get_path_at_pos (tree_view,
- bx - x_pos, by - y_pos,
- &path, &tv_column, NULL, NULL);
- if (ret_val)
- {
- gint index, column;
-
- column = get_column_number (tree_view, tv_column, FALSE);
- index = get_index (tree_view, path, column);
- gtk_tree_path_free (path);
-
- return gail_tree_view_ref_child (ATK_OBJECT (component), index);
- }
- else
- {
- g_warning ("gail_tree_view_ref_accessible_at_point: gtk_tree_view_get_path_at_pos () failed\n");
- }
- return NULL;
-}
-
-/* atktable.h */
-
-static void
-atk_table_interface_init (AtkTableIface *iface)
-{
- iface->ref_at = gail_tree_view_table_ref_at;
- iface->get_n_rows = gail_tree_view_get_n_rows;
- iface->get_n_columns = gail_tree_view_get_n_columns;
- iface->get_index_at = gail_tree_view_get_index_at;
- iface->get_column_at_index = gail_tree_view_get_column_at_index;
- iface->get_row_at_index = gail_tree_view_get_row_at_index;
- iface->is_row_selected = gail_tree_view_is_row_selected;
- iface->is_selected = gail_tree_view_is_selected;
- iface->get_selected_rows = gail_tree_view_get_selected_rows;
- iface->add_row_selection = gail_tree_view_add_row_selection;
- iface->remove_row_selection = gail_tree_view_remove_row_selection;
- iface->get_column_extent_at = NULL;
- iface->get_row_extent_at = NULL;
- iface->get_row_header = gail_tree_view_get_row_header;
- iface->set_row_header = gail_tree_view_set_row_header;
- iface->get_column_header = gail_tree_view_get_column_header;
- iface->set_column_header = gail_tree_view_set_column_header;
- iface->get_caption = gail_tree_view_get_caption;
- iface->set_caption = gail_tree_view_set_caption;
- iface->get_summary = gail_tree_view_get_summary;
- iface->set_summary = gail_tree_view_set_summary;
- iface->get_row_description = gail_tree_view_get_row_description;
- iface->set_row_description = gail_tree_view_set_row_description;
- iface->get_column_description = gail_tree_view_get_column_description;
- iface->set_column_description = gail_tree_view_set_column_description;
-}
-
-static gint
-gail_tree_view_get_index_at (AtkTable *table,
- gint row,
- gint column)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- gint actual_column;
- gint n_cols, n_rows;
- GtkTreeIter iter;
- GtkTreePath *path;
- gint index;
-
- n_cols = atk_table_get_n_columns (table);
- n_rows = atk_table_get_n_rows (table);
-
- if (row >= n_rows ||
- column >= n_cols)
- return -1;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- tree_view = GTK_TREE_VIEW (widget);
- actual_column = get_actual_column_number (tree_view, column);
-
- set_iter_nth_row (tree_view, &iter, row);
- path = gtk_tree_model_get_path (gtk_tree_view_get_model (tree_view), &iter);
-
- index = get_index (tree_view, path, actual_column);
- gtk_tree_path_free (path);
-
- return index;
-}
-
-static gint
-gail_tree_view_get_column_at_index (AtkTable *table,
- gint index)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- gint n_columns;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- tree_view = GTK_TREE_VIEW (widget);
- n_columns = get_n_actual_columns (tree_view);
-
- if (n_columns == 0)
- return 0;
- index = index % n_columns;
-
- return get_visible_column_number (tree_view, index);
-}
-
-static gint
-gail_tree_view_get_row_at_index (AtkTable *table,
- gint index)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreePath *path;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return -1;
-
- tree_view = GTK_TREE_VIEW (widget);
- if (get_path_column_from_index (tree_view, index, &path, NULL))
- {
- gint row = get_row_from_tree_path (tree_view, path);
- gtk_tree_path_free (path);
- return row;
- }
- else
- return -1;
-}
-
-static AtkObject*
-gail_tree_view_table_ref_at (AtkTable *table,
- gint row,
- gint column)
-{
- gint index;
-
- index = gail_tree_view_get_index_at (table, row, column);
- if (index == -1)
- return NULL;
-
- return gail_tree_view_ref_child (ATK_OBJECT (table), index);
-}
-
-static gint
-gail_tree_view_get_n_rows (AtkTable *table)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
- gint n_rows;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- tree_view = GTK_TREE_VIEW (widget);
- tree_model = gtk_tree_view_get_model (tree_view);
-
- if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
- /*
- * If working with a LIST store, then this is a faster way
- * to get the number of rows.
- */
- n_rows = gtk_tree_model_iter_n_children (tree_model, NULL);
- else
- {
- GtkTreePath *root_tree;
-
- n_rows = 0;
- root_tree = gtk_tree_path_new_first ();
- iterate_thru_children (tree_view, tree_model,
- root_tree, NULL, &n_rows, 0);
- gtk_tree_path_free (root_tree);
- }
-
- return n_rows;
-}
-
-/*
- * The function get_n_actual_columns returns the number of columns in the
- * GtkTreeView. i.e. it include both visible and non-visible columns.
- */
-static gint
-get_n_actual_columns (GtkTreeView *tree_view)
-{
- GList *columns;
- gint n_cols;
-
- columns = gtk_tree_view_get_columns (tree_view);
- n_cols = g_list_length (columns);
- g_list_free (columns);
- return n_cols;
-}
-
-static gint
-gail_tree_view_get_n_columns (AtkTable *table)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeViewColumn *tv_col;
- gint n_cols = 0;
- gint i = 0;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- tree_view = GTK_TREE_VIEW (widget);
- tv_col = gtk_tree_view_get_column (tree_view, i);
-
- while (tv_col != NULL)
- {
- if (gtk_tree_view_column_get_visible (tv_col))
- n_cols++;
-
- i++;
- tv_col = gtk_tree_view_get_column (tree_view, i);
- }
-
- return n_cols;
-}
-
-static gboolean
-gail_tree_view_is_row_selected (AtkTable *table,
- gint row)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeSelection *selection;
- GtkTreeIter iter;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- if (row < 0)
- return FALSE;
-
- tree_view = GTK_TREE_VIEW (widget);
-
- selection = gtk_tree_view_get_selection (tree_view);
-
- set_iter_nth_row (tree_view, &iter, row);
-
- return gtk_tree_selection_iter_is_selected (selection, &iter);
-}
-
-static gboolean
-gail_tree_view_is_selected (AtkTable *table,
- gint row,
- gint column)
-{
- return gail_tree_view_is_row_selected (table, row);
-}
-
-static gint
-gail_tree_view_get_selected_rows (AtkTable *table,
- gint **rows_selected)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
- GtkTreeIter iter;
- GtkTreeSelection *selection;
- GtkTreePath *tree_path;
- gint ret_val = 0;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return 0;
-
- tree_view = GTK_TREE_VIEW (widget);
-
- selection = gtk_tree_view_get_selection (tree_view);
-
- switch (gtk_tree_selection_get_mode (selection))
- {
- case GTK_SELECTION_SINGLE:
- case GTK_SELECTION_BROWSE:
- if (gtk_tree_selection_get_selected (selection, &tree_model, &iter))
- {
- gint row;
-
- if (rows_selected)
- {
- *rows_selected = (gint *)g_malloc (sizeof(gint));
- tree_path = gtk_tree_model_get_path (tree_model, &iter);
- row = get_row_from_tree_path (tree_view, tree_path);
- gtk_tree_path_free (tree_path);
-
- /* shouldn't ever happen */
- g_return_val_if_fail (row != -1, 0);
-
- *rows_selected[0] = row;
- }
- ret_val = 1;
- }
- break;
- case GTK_SELECTION_MULTIPLE:
- {
- GPtrArray *array = g_ptr_array_new();
-
- gtk_tree_selection_selected_foreach (selection,
- get_selected_rows,
- array);
- ret_val = array->len;
-
- if (rows_selected && ret_val)
- {
- gint i;
- *rows_selected = (gint *) g_malloc (ret_val * sizeof (gint));
-
- for (i = 0; i < ret_val; i++)
- {
- gint row;
-
- tree_path = (GtkTreePath *) g_ptr_array_index (array, i);
- row = get_row_from_tree_path (tree_view, tree_path);
- gtk_tree_path_free (tree_path);
- (*rows_selected)[i] = row;
- }
- }
- g_ptr_array_free (array, FALSE);
- }
- break;
- case GTK_SELECTION_NONE:
- break;
- }
- return ret_val;
-}
-
-static gboolean
-gail_tree_view_add_row_selection (AtkTable *table,
- gint row)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
- GtkTreeSelection *selection;
- GtkTreePath *tree_path;
- GtkTreeIter iter_to_row;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- if (!gail_tree_view_is_row_selected (table, row))
- {
- tree_view = GTK_TREE_VIEW (widget);
- tree_model = gtk_tree_view_get_model (tree_view);
- selection = gtk_tree_view_get_selection (tree_view);
-
- if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
- {
- tree_path = gtk_tree_path_new ();
- gtk_tree_path_append_index (tree_path, row);
- gtk_tree_selection_select_path (selection,tree_path);
- gtk_tree_path_free (tree_path);
- }
- else
- {
- set_iter_nth_row (tree_view, &iter_to_row, row);
- gtk_tree_selection_select_iter (selection, &iter_to_row);
- }
- }
-
- return gail_tree_view_is_row_selected (table, row);
-}
-
-static gboolean
-gail_tree_view_remove_row_selection (AtkTable *table,
- gint row)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeSelection *selection;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- tree_view = GTK_TREE_VIEW (widget);
-
- selection = gtk_tree_view_get_selection (tree_view);
-
- if (gail_tree_view_is_row_selected (table, row))
- {
- gtk_tree_selection_unselect_all (selection);
- return TRUE;
- }
- else return FALSE;
-}
-
-static AtkObject*
-gail_tree_view_get_row_header (AtkTable *table,
- gint row)
-{
- GailTreeViewRowInfo *row_info;
-
- row_info = get_row_info (table, row);
- if (row_info)
- return row_info->header;
- else
- return NULL;
-}
-
-static void
-gail_tree_view_set_row_header (AtkTable *table,
- gint row,
- AtkObject *header)
-{
- set_row_data (table, row, header, NULL, TRUE);
-}
-
-static AtkObject*
-gail_tree_view_get_column_header (AtkTable *table,
- gint in_col)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeViewColumn *tv_col;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- tree_view = GTK_TREE_VIEW (widget);
- tv_col = get_column (tree_view, in_col);
- return get_header_from_column (tv_col);
-}
-
-static void
-gail_tree_view_set_column_header (AtkTable *table,
- gint in_col,
- AtkObject *header)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeViewColumn *tv_col;
- AtkPropertyValues values = { NULL };
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- tree_view = GTK_TREE_VIEW (widget);
- tv_col = get_column (tree_view, in_col);
- if (tv_col == NULL)
- return;
-
- g_object_set_qdata_full (G_OBJECT (tv_col),
- quark_column_header_object,
- header,
- g_object_unref);
- if (header)
- g_object_ref (header);
- g_value_init (&values.new_value, G_TYPE_INT);
- g_value_set_int (&values.new_value, in_col);
-
- values.property_name = "accessible-table-column-header";
- g_signal_emit_by_name (table,
- "property_change::accessible-table-column-header",
- &values, NULL);
-}
-
-static AtkObject*
-gail_tree_view_get_caption (AtkTable *table)
-{
- GailTreeView* obj = GAIL_TREE_VIEW (table);
-
- return obj->caption;
-}
-
-static void
-gail_tree_view_set_caption (AtkTable *table,
- AtkObject *caption)
-{
- GailTreeView* obj = GAIL_TREE_VIEW (table);
- AtkPropertyValues values = { NULL };
- AtkObject *old_caption;
-
- old_caption = obj->caption;
- obj->caption = caption;
- if (obj->caption)
- g_object_ref (obj->caption);
- g_value_init (&values.old_value, G_TYPE_POINTER);
- g_value_set_pointer (&values.old_value, old_caption);
- g_value_init (&values.new_value, G_TYPE_POINTER);
- g_value_set_pointer (&values.new_value, obj->caption);
-
- values.property_name = "accessible-table-caption-object";
- g_signal_emit_by_name (table,
- "property_change::accessible-table-caption-object",
- &values, NULL);
- if (old_caption)
- g_object_unref (old_caption);
-}
-
-static const gchar*
-gail_tree_view_get_column_description (AtkTable *table,
- gint in_col)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeViewColumn *tv_col;
- gchar *rc;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- tree_view = GTK_TREE_VIEW (widget);
- tv_col = get_column (tree_view, in_col);
- if (tv_col == NULL)
- return NULL;
-
- rc = g_object_get_qdata (G_OBJECT (tv_col),
- quark_column_desc_object);
-
- if (rc != NULL)
- return rc;
- else
- {
- gchar *title_text;
-
- g_object_get (tv_col, "title", &title_text, NULL);
- return title_text;
- }
-}
-
-static void
-gail_tree_view_set_column_description (AtkTable *table,
- gint in_col,
- const gchar *description)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeViewColumn *tv_col;
- AtkPropertyValues values = { NULL };
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- tree_view = GTK_TREE_VIEW (widget);
- tv_col = get_column (tree_view, in_col);
- if (tv_col == NULL)
- return;
-
- g_object_set_qdata_full (G_OBJECT (tv_col),
- quark_column_desc_object,
- g_strdup (description),
- g_free);
- g_value_init (&values.new_value, G_TYPE_INT);
- g_value_set_int (&values.new_value, in_col);
-
- values.property_name = "accessible-table-column-description";
- g_signal_emit_by_name (table,
- "property_change::accessible-table-column-description",
- &values, NULL);
-}
-
-static const gchar*
-gail_tree_view_get_row_description (AtkTable *table,
- gint row)
-{
- GailTreeViewRowInfo *row_info;
-
- row_info = get_row_info (table, row);
- if (row_info)
- return row_info->description;
- else
- return NULL;
-}
-
-static void
-gail_tree_view_set_row_description (AtkTable *table,
- gint row,
- const gchar *description)
-{
- set_row_data (table, row, NULL, description, FALSE);
-}
-
-static AtkObject*
-gail_tree_view_get_summary (AtkTable *table)
-{
- GailTreeView* obj = GAIL_TREE_VIEW (table);
-
- return obj->summary;
-}
-
-static void
-gail_tree_view_set_summary (AtkTable *table,
- AtkObject *accessible)
-{
- GailTreeView* obj = GAIL_TREE_VIEW (table);
- AtkPropertyValues values = { NULL };
- AtkObject *old_summary;
-
- old_summary = obj->summary;
- obj->summary = accessible;
- if (obj->summary)
- g_object_ref (obj->summary);
- g_value_init (&values.old_value, G_TYPE_POINTER);
- g_value_set_pointer (&values.old_value, old_summary);
- g_value_init (&values.new_value, G_TYPE_POINTER);
- g_value_set_pointer (&values.new_value, obj->summary);
-
- values.property_name = "accessible-table-summary";
- g_signal_emit_by_name (table,
- "property_change::accessible-table-ummary",
- &values, NULL);
- if (old_summary)
- g_object_unref (old_summary);
-}
-
-static void
-set_row_data (AtkTable *table,
- gint row,
- AtkObject *header,
- const gchar *description,
- gboolean is_header)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
- GailTreeView* obj = GAIL_TREE_VIEW (table);
- GailTreeViewRowInfo* row_info;
- GtkTreePath *path;
- GtkTreeIter iter;
- GArray *array;
- gboolean found = FALSE;
- gint i;
- AtkPropertyValues values = { NULL };
- gchar *signal_name;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- tree_view = GTK_TREE_VIEW (widget);
- tree_model = gtk_tree_view_get_model (tree_view);
-
- set_iter_nth_row (tree_view, &iter, row);
- path = gtk_tree_model_get_path (tree_model, &iter);
-
- if (obj->row_data == NULL)
- obj->row_data = g_array_sized_new (FALSE, TRUE,
- sizeof(GailTreeViewRowInfo *), 0);
-
- array = obj->row_data;
-
- for (i = 0; i < array->len; i++)
- {
- GtkTreePath *row_path;
-
- row_info = g_array_index (array, GailTreeViewRowInfo*, i);
- row_path = gtk_tree_row_reference_get_path (row_info->row_ref);
-
- if (row_path != NULL)
- {
- if (path && gtk_tree_path_compare (row_path, path) == 0)
- found = TRUE;
-
- gtk_tree_path_free (row_path);
-
- if (found)
- {
- if (is_header)
- {
- if (row_info->header)
- g_object_unref (row_info->header);
- row_info->header = header;
- if (row_info->header)
- g_object_ref (row_info->header);
- }
- else
- {
- g_free (row_info->description);
- row_info->description = g_strdup (description);
- }
- break;
- }
- }
- }
-
- if (!found)
- {
- /* if not found */
- row_info = g_malloc (sizeof(GailTreeViewRowInfo));
- row_info->row_ref = gtk_tree_row_reference_new (tree_model, path);
- if (is_header)
- {
- row_info->header = header;
- if (row_info->header)
- g_object_ref (row_info->header);
- row_info->description = NULL;
- }
- else
- {
- row_info->header = NULL;
- row_info->description = g_strdup (description);
- }
- g_array_append_val (array, row_info);
- }
- g_value_init (&values.new_value, G_TYPE_INT);
- g_value_set_int (&values.new_value, row);
-
- if (is_header)
- {
- values.property_name = "accessible-table-row-header";
- signal_name = "property_change::accessible-table-row-header";
- }
- else
- {
- values.property_name = "accessible-table-row-description";
- signal_name = "property-change::accessible-table-row-description";
- }
- g_signal_emit_by_name (table,
- signal_name,
- &values, NULL);
-
- gtk_tree_path_free (path);
-}
-
-
-static GailTreeViewRowInfo*
-get_row_info (AtkTable *table,
- gint row)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
- GailTreeView* obj = GAIL_TREE_VIEW (table);
- GtkTreePath *path;
- GtkTreeIter iter;
- GArray *array;
- GailTreeViewRowInfo *rc = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (table));
- if (widget == NULL)
- /* State is defunct */
- return NULL;
-
- tree_view = GTK_TREE_VIEW (widget);
- tree_model = gtk_tree_view_get_model (tree_view);
-
- set_iter_nth_row (tree_view, &iter, row);
- path = gtk_tree_model_get_path (tree_model, &iter);
- array = obj->row_data;
-
- if (array != NULL)
- {
- GailTreeViewRowInfo *row_info;
- GtkTreePath *row_path;
- gint i;
-
- for (i = 0; i < array->len; i++)
- {
- row_info = g_array_index (array, GailTreeViewRowInfo*, i);
- row_path = gtk_tree_row_reference_get_path (row_info->row_ref);
- if (row_path != NULL)
- {
- if (path && gtk_tree_path_compare (row_path, path) == 0)
- rc = row_info;
-
- gtk_tree_path_free (row_path);
-
- if (rc != NULL)
- break;
- }
- }
- }
-
- gtk_tree_path_free (path);
- return rc;
-}
-/* atkselection.h */
-
-static void atk_selection_interface_init (AtkSelectionIface *iface)
-{
- iface->add_selection = gail_tree_view_add_selection;
- iface->clear_selection = gail_tree_view_clear_selection;
- iface->ref_selection = gail_tree_view_ref_selection;
- iface->get_selection_count = gail_tree_view_get_selection_count;
- iface->is_child_selected = gail_tree_view_is_child_selected;
-}
-
-static gboolean
-gail_tree_view_add_selection (AtkSelection *selection,
- gint i)
-{
- AtkTable *table;
- gint n_columns;
- gint row;
-
- table = ATK_TABLE (selection);
- n_columns = gail_tree_view_get_n_columns (table);
- if (n_columns != 1)
- return FALSE;
-
- row = gail_tree_view_get_row_at_index (table, i);
- return gail_tree_view_add_row_selection (table, row);
-}
-
-static gboolean
-gail_tree_view_clear_selection (AtkSelection *selection)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeSelection *tree_selection;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- tree_view = GTK_TREE_VIEW (widget);
-
- tree_selection = gtk_tree_view_get_selection (tree_view);
- gtk_tree_selection_unselect_all (tree_selection);
-
- return TRUE;
-}
-
-static AtkObject*
-gail_tree_view_ref_selection (AtkSelection *selection,
- gint i)
-{
- AtkTable *table;
- gint row;
- gint n_selected;
- gint n_columns;
- gint *selected;
-
- table = ATK_TABLE (selection);
- n_columns = gail_tree_view_get_n_columns (table);
- n_selected = gail_tree_view_get_selected_rows (table, &selected);
- if (i >= n_columns * n_selected)
- return NULL;
-
- row = selected[i / n_columns];
- g_free (selected);
-
- return gail_tree_view_table_ref_at (table, row, i % n_columns);
-}
-
-static gint
-gail_tree_view_get_selection_count (AtkSelection *selection)
-{
- AtkTable *table;
- gint n_selected;
-
- table = ATK_TABLE (selection);
- n_selected = gail_tree_view_get_selected_rows (table, NULL);
- if (n_selected > 0)
- n_selected *= gail_tree_view_get_n_columns (table);
- return n_selected;
-}
-
-static gboolean
-gail_tree_view_is_child_selected (AtkSelection *selection,
- gint i)
-{
- GtkWidget *widget;
- gint row;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- row = atk_table_get_row_at_index (ATK_TABLE (selection), i);
-
- return gail_tree_view_is_row_selected (ATK_TABLE (selection), row);
-}
-
-
-static void gail_cell_parent_interface_init (GailCellParentIface *iface)
-{
- iface->get_cell_extents = gail_tree_view_get_cell_extents;
- iface->get_cell_area = gail_tree_view_get_cell_area;
- iface->grab_focus = gail_tree_view_grab_cell_focus;
-}
-
-static void
-gail_tree_view_get_cell_extents (GailCellParent *parent,
- GailCell *cell,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GdkWindow *bin_window;
- GdkRectangle cell_rect;
- gint w_x, w_y;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- tree_view = GTK_TREE_VIEW (widget);
- gail_tree_view_get_cell_area (parent, cell, &cell_rect);
- bin_window = gtk_tree_view_get_bin_window (tree_view);
- gdk_window_get_origin (bin_window, &w_x, &w_y);
-
- if (coord_type == ATK_XY_WINDOW)
- {
- GdkWindow *window;
- gint x_toplevel, y_toplevel;
-
- window = gdk_window_get_toplevel (bin_window);
- gdk_window_get_origin (window, &x_toplevel, &y_toplevel);
-
- w_x -= x_toplevel;
- w_y -= y_toplevel;
- }
-
- *width = cell_rect.width;
- *height = cell_rect.height;
- if (is_cell_showing (tree_view, &cell_rect))
- {
- *x = cell_rect.x + w_x;
- *y = cell_rect.y + w_y;
- }
- else
- {
- *x = G_MININT;
- *y = G_MININT;
- }
-}
-
-#define EXTRA_EXPANDER_PADDING 4
-
-static void
-gail_tree_view_get_cell_area (GailCellParent *parent,
- GailCell *cell,
- GdkRectangle *cell_rect)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeViewColumn *tv_col;
- GtkTreePath *path;
- AtkObject *parent_cell;
- GailTreeViewCellInfo *cell_info;
- GailCell *top_cell;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
- if (widget == NULL)
- /* State is defunct */
- return;
-
- tree_view = GTK_TREE_VIEW (widget);
- parent_cell = atk_object_get_parent (ATK_OBJECT (cell));
- if (parent_cell != ATK_OBJECT (parent))
- {
- /*
- * GailCell is in a GailContainerCell
- */
- top_cell = GAIL_CELL (parent_cell);
- }
- else
- {
- top_cell = cell;
- }
- cell_info = find_cell_info (GAIL_TREE_VIEW (parent), top_cell, NULL, TRUE);
- gail_return_if_fail (cell_info);
- gail_return_if_fail (cell_info->cell_col_ref);
- gail_return_if_fail (cell_info->cell_row_ref);
- path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- tv_col = cell_info->cell_col_ref;
- if (path && cell_info->in_use)
- {
- GtkTreeViewColumn *expander_column;
- gint focus_line_width;
-
- gtk_tree_view_get_cell_area (tree_view, path, tv_col, cell_rect);
- expander_column = gtk_tree_view_get_expander_column (tree_view);
- if (expander_column == tv_col)
- {
- gint expander_size;
-
- gtk_widget_style_get (widget,
- "expander_size", &expander_size,
- NULL);
-
- cell_rect->x += expander_size + EXTRA_EXPANDER_PADDING;
- cell_rect->width -= expander_size + EXTRA_EXPANDER_PADDING;
- }
- gtk_widget_style_get (widget,
- "focus-line-width", &focus_line_width,
- NULL);
-
- cell_rect->x += focus_line_width;
- cell_rect->width -= 2 * focus_line_width;
-
- gtk_tree_path_free (path);
-
- /*
- * A column has more than one renderer so we find the position and width
- * of each.
- */
- if (top_cell != cell)
- {
- gint cell_index;
- gboolean found;
- gint cell_start;
- gint cell_width;
- GList *renderers;
- GtkCellRenderer *renderer;
-
- cell_index = atk_object_get_index_in_parent (ATK_OBJECT (cell));
- renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tv_col));
- renderer = g_list_nth_data (renderers, cell_index);
-
- found = gtk_tree_view_column_cell_get_position (tv_col, renderer, &cell_start, &cell_width);
- if (found)
- {
- cell_rect->x += cell_start;
- cell_rect->width = cell_width;
- }
- g_list_free (renderers);
- }
-
- }
-}
-
-static gboolean
-gail_tree_view_grab_cell_focus (GailCellParent *parent,
- GailCell *cell)
-{
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeViewColumn *tv_col;
- GtkTreePath *path;
- AtkObject *parent_cell;
- AtkObject *cell_object;
- GailTreeViewCellInfo *cell_info;
- GtkCellRenderer *renderer = NULL;
- GtkWidget *toplevel;
- gint index;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
- if (widget == NULL)
- /* State is defunct */
- return FALSE;
-
- tree_view = GTK_TREE_VIEW (widget);
-
- cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
- gail_return_val_if_fail (cell_info, FALSE);
- gail_return_val_if_fail (cell_info->cell_col_ref, FALSE);
- gail_return_val_if_fail (cell_info->cell_row_ref, FALSE);
- cell_object = ATK_OBJECT (cell);
- parent_cell = atk_object_get_parent (cell_object);
- tv_col = cell_info->cell_col_ref;
- if (parent_cell != ATK_OBJECT (parent))
- {
- /*
- * GailCell is in a GailContainerCell.
- * The GtkTreeViewColumn has multiple renderers;
- * find the corresponding one.
- */
- GList *renderers;
-
- renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tv_col));
- if (cell_info->in_use) {
- index = atk_object_get_index_in_parent (cell_object);
- renderer = g_list_nth_data (renderers, index);
- }
- g_list_free (renderers);
- }
- path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- if (path && cell_info->in_use)
- {
- if (renderer)
- gtk_tree_view_set_cursor_on_cell (tree_view, path, tv_col, renderer, FALSE);
- else
- gtk_tree_view_set_cursor (tree_view, path, tv_col, FALSE);
-
- gtk_tree_path_free (path);
- gtk_widget_grab_focus (widget);
- toplevel = gtk_widget_get_toplevel (widget);
- if (gtk_widget_is_toplevel (toplevel))
- {
-#ifdef GDK_WINDOWING_X11
- gtk_window_present_with_time (GTK_WINDOW (toplevel),
- gdk_x11_get_server_time (gtk_widget_get_window (widget)));
-#else
- gtk_window_present (GTK_WINDOW (toplevel));
-#endif
- }
-
- return TRUE;
- }
- else
- return FALSE;
-}
-
-/* signal handling */
-
-static gboolean
-gail_tree_view_expand_row_gtk (GtkTreeView *tree_view,
- GtkTreeIter *iter,
- GtkTreePath *path)
-{
- AtkObject *atk_obj;
- GailTreeView *gailview;
-
- g_assert (GTK_IS_TREE_VIEW (tree_view));
-
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
-
- g_assert (GAIL_IS_TREE_VIEW (atk_obj));
-
- gailview = GAIL_TREE_VIEW (atk_obj);
-
- /*
- * The visible rectangle has not been updated when this signal is emitted
- * so we process the signal when the GTK processing is completed
- */
- /* this seems wrong since it overwrites any other pending expand handlers... */
- gailview->idle_expand_path = gtk_tree_path_copy (path);
- if (gailview->idle_expand_id)
- g_source_remove (gailview->idle_expand_id);
- gailview->idle_expand_id = gdk_threads_add_idle (idle_expand_row, gailview);
- return FALSE;
-}
-
-static gint
-idle_expand_row (gpointer data)
-{
- GailTreeView *gailview = data;
- GtkTreePath *path;
- GtkTreeView *tree_view;
- GtkTreeIter iter;
- GtkTreeModel *tree_model;
- gint n_inserted, row;
-
- gailview->idle_expand_id = 0;
-
- path = gailview->idle_expand_path;
- tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (gailview)));
-
- g_assert (GTK_IS_TREE_VIEW (tree_view));
-
- tree_model = gtk_tree_view_get_model(tree_view);
- if (!tree_model)
- return FALSE;
-
- if (!path || !gtk_tree_model_get_iter (tree_model, &iter, path))
- return FALSE;
-
- /*
- * Update visibility of cells below expansion row
- */
- traverse_cells (gailview, path, FALSE, FALSE);
- /*
- * Figure out number of visible children, the following test
- * should not fail
- */
- if (gtk_tree_model_iter_has_child (tree_model, &iter))
- {
- GtkTreePath *path_copy;
-
- /*
- * By passing path into this function, we find the number of
- * visible children of path.
- */
- path_copy = gtk_tree_path_copy (path);
- gtk_tree_path_append_index(path_copy, 0);
-
- n_inserted = 0;
- iterate_thru_children (tree_view, tree_model,
- path_copy, NULL, &n_inserted, 0);
- gtk_tree_path_free (path_copy);
- }
- else
- {
- /* We can get here if the row expanded callback deleted the row */
- return FALSE;
- }
-
- /* Set expand state */
- set_expand_state (tree_view, tree_model, gailview, path, TRUE);
-
- row = get_row_from_tree_path (tree_view, path);
-
- /* shouldn't ever happen */
- if (row == -1)
- g_assert_not_reached ();
-
- /* Must add 1 because the "added rows" are below the row being expanded */
- row += 1;
-
- g_signal_emit_by_name (gailview, "row_inserted", row, n_inserted);
-
- gailview->idle_expand_path = NULL;
-
- gtk_tree_path_free (path);
-
- return FALSE;
-}
-
-static gboolean
-gail_tree_view_collapse_row_gtk (GtkTreeView *tree_view,
- GtkTreeIter *iter,
- GtkTreePath *path)
-{
- GtkTreeModel *tree_model;
- AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
- GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
- gint row;
-
- tree_model = gtk_tree_view_get_model (tree_view);
-
- clean_rows (gailview);
-
- /*
- * Update visibility of cells below collapsed row
- */
- traverse_cells (gailview, path, FALSE, FALSE);
- /* Set collapse state */
- set_expand_state (tree_view, tree_model, gailview, path, FALSE);
-
- gail_return_val_if_fail (gailview->n_children_deleted, FALSE);
- row = get_row_from_tree_path (tree_view, path);
- gail_return_val_if_fail (row != -1, FALSE);
- g_signal_emit_by_name (atk_obj, "row_deleted", row,
- gailview->n_children_deleted);
- gailview->n_children_deleted = 0;
- return FALSE;
-}
-
-static void
-gail_tree_view_size_allocate_gtk (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- AtkObject *atk_obj = gtk_widget_get_accessible (widget);
- GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
-
- /*
- * If the size allocation changes, the visibility of cells may change so
- * update the cells visibility.
- */
- traverse_cells (gailview, NULL, FALSE, FALSE);
-}
-
-static void
-gail_tree_view_changed_gtk (GtkTreeSelection *selection,
- gpointer data)
-{
- GailTreeView *gailview;
- GtkTreeView *tree_view;
- GtkWidget *widget;
- GList *cell_list;
- GList *l;
- GailTreeViewCellInfo *info;
- GtkTreeSelection *tree_selection;
- GtkTreePath *path;
-
- gailview = GAIL_TREE_VIEW (data);
- cell_list = gailview->cell_data;
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gailview));
- if (widget == NULL)
- /*
- * destroy signal emitted for widget
- */
- return;
- tree_view = GTK_TREE_VIEW (widget);
-
- tree_selection = gtk_tree_view_get_selection (tree_view);
-
- clean_rows (gailview);
-
- for (l = cell_list; l; l = l->next)
- {
- info = (GailTreeViewCellInfo *) (l->data);
-
- if (info->in_use)
- {
- gail_cell_remove_state (info->cell, ATK_STATE_SELECTED, TRUE);
-
- path = gtk_tree_row_reference_get_path (info->cell_row_ref);
- if (path && gtk_tree_selection_path_is_selected (tree_selection, path))
- gail_cell_add_state (info->cell, ATK_STATE_SELECTED, TRUE);
- gtk_tree_path_free (path);
- }
- }
- if (gtk_widget_get_realized (widget))
- g_signal_emit_by_name (gailview, "selection_changed");
-}
-
-static void
-columns_changed (GtkTreeView *tree_view)
-{
- AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET(tree_view));
- GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
- GList *tv_cols, *tmp_list;
- gboolean column_found;
- gboolean move_found = FALSE;
- gboolean stale_set = FALSE;
- gint column_count = 0;
- gint i;
-
- /*
- * This function must determine if the change is an add, delete or
- * a move based upon its cache of TreeViewColumns in
- * gailview->col_data
- */
- tv_cols = gtk_tree_view_get_columns (tree_view);
-
- /* check for adds or moves */
- for (tmp_list = tv_cols; tmp_list; tmp_list = tmp_list->next)
- {
- column_found = FALSE;
-
- for (i = 0; i < gailview->col_data->len; i++)
- {
-
- if ((GtkTreeViewColumn *)tmp_list->data ==
- (GtkTreeViewColumn *)g_array_index (gailview->col_data,
- GtkTreeViewColumn *, i))
- {
- column_found = TRUE;
-
- /* If the column isn't in the same position, a move happened */
- if (!move_found && i != column_count)
- {
- if (!stale_set)
- {
- /* Set all rows to ATK_STATE_STALE */
- traverse_cells (gailview, NULL, TRUE, FALSE);
- stale_set = TRUE;
- }
-
- /* Just emit one column reordered signal when a move happens */
- g_signal_emit_by_name (atk_obj, "column_reordered");
- move_found = TRUE;
- }
-
- break;
- }
- }
-
- /*
- * If column_found is FALSE, then an insert happened for column
- * number column_count
- */
- if (!column_found)
- {
- gint n_cols, n_rows, row;
-
- if (!stale_set)
- {
- /* Set all rows to ATK_STATE_STALE */
- traverse_cells (gailview, NULL, TRUE, FALSE);
- stale_set = TRUE;
- }
-
- /* Generate column-inserted signal */
- g_signal_emit_by_name (atk_obj, "column_inserted", column_count, 1);
-
- /* Generate children-changed signals */
- n_rows = get_row_count (gtk_tree_view_get_model (tree_view));
- n_cols = get_n_actual_columns (tree_view);
- for (row = 0; row < n_rows; row++)
- {
- /*
- * Pass NULL as the child object, i.e. 4th argument.
- */
- g_signal_emit_by_name (atk_obj, "children_changed::add",
- ((row * n_cols) + column_count), NULL, NULL);
- }
- }
-
- column_count++;
- }
-
- /* check for deletes */
- for (i = 0; i < gailview->col_data->len; i++)
- {
- column_found = FALSE;
-
- for (tmp_list = tv_cols; tmp_list; tmp_list = tmp_list->next)
- {
- if ((GtkTreeViewColumn *)tmp_list->data ==
- (GtkTreeViewColumn *)g_array_index (gailview->col_data,
- GtkTreeViewColumn *, i))
- {
- column_found = TRUE;
- break;
- }
- }
-
- /*
- * If column_found is FALSE, then a delete happened for column
- * number i
- */
- if (!column_found)
- {
- gint n_rows, n_cols, row;
-
- clean_cols (gailview,
- (GtkTreeViewColumn *)g_array_index (gailview->col_data,
- GtkTreeViewColumn *, i));
-
- if (!stale_set)
- {
- /* Set all rows to ATK_STATE_STALE */
- traverse_cells (gailview, NULL, TRUE, FALSE);
- stale_set = TRUE;
- }
-
- /* Generate column-deleted signal */
- g_signal_emit_by_name (atk_obj, "column_deleted", i, 1);
-
- /* Generate children-changed signals */
- n_rows = get_row_count (gtk_tree_view_get_model (tree_view));
- n_cols = get_n_actual_columns (tree_view);
- for (row = 0; row < n_rows; row++)
- {
- /*
- * Pass NULL as the child object, 4th argument.
- */
- g_signal_emit_by_name (atk_obj, "children_changed::remove",
- ((row * n_cols) + column_count), NULL, NULL);
- }
- }
- }
-
- /* rebuild the array */
-
- g_array_free (gailview->col_data, TRUE);
- gailview->col_data = g_array_sized_new (FALSE, TRUE,
- sizeof(GtkTreeViewColumn *), 0);
-
- for (tmp_list = tv_cols; tmp_list; tmp_list = tmp_list->next)
- g_array_append_val (gailview->col_data, tmp_list->data);
- g_list_free (tv_cols);
-}
-
-static void
-cursor_changed (GtkTreeView *tree_view)
-{
- GailTreeView *gailview;
-
- gailview = GAIL_TREE_VIEW (gtk_widget_get_accessible (GTK_WIDGET (tree_view)));
- if (gailview->idle_cursor_changed_id != 0)
- return;
-
- /*
- * We notify the focus change in a idle handler so that the processing
- * of the cursor change is completed when the focus handler is called.
- * This will allow actions to be called in the focus handler
- */
- gailview->idle_cursor_changed_id = gdk_threads_add_idle (idle_cursor_changed, gailview);
-}
-
-static gint
-idle_cursor_changed (gpointer data)
-{
- GailTreeView *gail_tree_view = GAIL_TREE_VIEW (data);
- GtkTreeView *tree_view;
- GtkWidget *widget;
- AtkObject *cell;
-
- gail_tree_view->idle_cursor_changed_id = 0;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gail_tree_view));
- /*
- * Widget has been deleted
- */
- if (widget == NULL)
- return FALSE;
-
- tree_view = GTK_TREE_VIEW (widget);
-
- cell = gail_tree_view_ref_focus_cell (tree_view);
- if (cell)
- {
- if (cell != gail_tree_view->focus_cell)
- {
- if (gail_tree_view->focus_cell)
- {
- gail_cell_remove_state (GAIL_CELL (gail_tree_view->focus_cell), ATK_STATE_ACTIVE, FALSE);
- gail_cell_remove_state (GAIL_CELL (gail_tree_view->focus_cell), ATK_STATE_FOCUSED, FALSE);
- g_object_unref (gail_tree_view->focus_cell);
- }
- gail_tree_view->focus_cell = cell;
-
- if (gtk_widget_has_focus (widget))
- {
- gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_ACTIVE, FALSE);
- gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_FOCUSED, FALSE);
- }
- g_signal_emit_by_name (gail_tree_view,
- "active-descendant-changed",
- cell);
- }
- else
- g_object_unref (cell);
- }
-
- return FALSE;
-}
-
-static gboolean
-focus_in (GtkWidget *widget)
-{
- GtkTreeView *tree_view;
- GailTreeView *gail_tree_view;
- AtkStateSet *state_set;
- AtkObject *cell;
-
- tree_view = GTK_TREE_VIEW (widget);
- gail_tree_view = GAIL_TREE_VIEW (gtk_widget_get_accessible (widget));
-
- if (gail_tree_view->focus_cell == NULL)
- {
- cell = gail_tree_view_ref_focus_cell (tree_view);
- if (cell)
- {
- state_set = atk_object_ref_state_set (cell);
- if (state_set)
- {
- if (!atk_state_set_contains_state (state_set, ATK_STATE_FOCUSED))
- {
- gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_ACTIVE, FALSE);
- gail_tree_view->focus_cell = cell;
- gail_cell_add_state (GAIL_CELL (cell), ATK_STATE_FOCUSED, FALSE);
- g_signal_emit_by_name (gail_tree_view,
- "active-descendant-changed",
- cell);
- }
- g_object_unref (state_set);
- }
- }
- }
- return FALSE;
-}
-
-static gboolean
-focus_out (GtkWidget *widget)
-{
- GailTreeView *gail_tree_view;
-
- gail_tree_view = GAIL_TREE_VIEW (gtk_widget_get_accessible (widget));
- if (gail_tree_view->focus_cell)
- {
- gail_cell_remove_state (GAIL_CELL (gail_tree_view->focus_cell), ATK_STATE_ACTIVE, FALSE);
- gail_cell_remove_state (GAIL_CELL (gail_tree_view->focus_cell), ATK_STATE_FOCUSED, FALSE);
- g_object_unref (gail_tree_view->focus_cell);
- gail_tree_view->focus_cell = NULL;
- }
- return FALSE;
-}
-
-static void
-model_row_changed (GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- GtkTreeView *tree_view = GTK_TREE_VIEW(user_data);
- GailTreeView *gailview;
- GtkTreePath *cell_path;
- GList *l;
- GailTreeViewCellInfo *cell_info;
-
- gailview = GAIL_TREE_VIEW (gtk_widget_get_accessible (GTK_WIDGET (tree_view)));
-
- /* Loop through our cached cells */
- /* Must loop through them all */
- for (l = gailview->cell_data; l; l = l->next)
- {
- cell_info = (GailTreeViewCellInfo *) l->data;
- if (cell_info->in_use)
- {
- cell_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
-
- if (cell_path != NULL)
- {
- if (path && gtk_tree_path_compare (cell_path, path) == 0)
- {
- if (GAIL_IS_RENDERER_CELL (cell_info->cell))
- {
- update_cell_value (GAIL_RENDERER_CELL (cell_info->cell),
- gailview, TRUE);
- }
- }
- gtk_tree_path_free (cell_path);
- }
- }
- }
- g_signal_emit_by_name (gailview, "visible-data-changed");
-}
-
-static void
-column_visibility_changed (GObject *object,
- GParamSpec *pspec,
- gpointer user_data)
-{
- if (strcmp (pspec->name, "visible") == 0)
- {
- /*
- * A column has been made visible or invisible
- *
- * We update our cache of cells and emit model_changed signal
- */
- GtkTreeView *tree_view = (GtkTreeView *)user_data;
- GailTreeView *gailview;
- GList *l;
- GailTreeViewCellInfo *cell_info;
- GtkTreeViewColumn *this_col = GTK_TREE_VIEW_COLUMN (object);
- GtkTreeViewColumn *tv_col;
-
- gailview = GAIL_TREE_VIEW (gtk_widget_get_accessible (GTK_WIDGET (tree_view))
-);
- g_signal_emit_by_name (gailview, "model_changed");
-
- for (l = gailview->cell_data; l; l = l->next)
- {
- cell_info = (GailTreeViewCellInfo *) l->data;
- if (cell_info->in_use)
- {
- tv_col = cell_info->cell_col_ref;
- if (tv_col == this_col)
- {
- GtkTreePath *row_path;
- row_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- if (GAIL_IS_RENDERER_CELL (cell_info->cell))
- {
- if (gtk_tree_view_column_get_visible (tv_col))
- set_cell_visibility (tree_view,
- cell_info->cell,
- tv_col, row_path, FALSE);
- else
- {
- gail_cell_remove_state (cell_info->cell,
- ATK_STATE_VISIBLE, TRUE);
- gail_cell_remove_state (cell_info->cell,
- ATK_STATE_SHOWING, TRUE);
- }
- }
- gtk_tree_path_free (row_path);
- }
- }
- }
- }
-}
-
-static void
-model_row_inserted (GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- GtkTreeView *tree_view = (GtkTreeView *)user_data;
- GtkTreePath *path_copy;
- AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
- GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
- gint row, n_inserted, child_row;
-
- if (gailview->idle_expand_id)
- {
- g_source_remove (gailview->idle_expand_id);
- gailview->idle_expand_id = 0;
-
- /* don't do this if the insertion precedes the idle path, since it will now be invalid */
- if (path && gailview->idle_expand_path &&
- (gtk_tree_path_compare (path, gailview->idle_expand_path) > 0))
- set_expand_state (tree_view, tree_model, gailview, gailview->idle_expand_path, FALSE);
- if (gailview->idle_expand_path)
- gtk_tree_path_free (gailview->idle_expand_path);
- }
- /* Check to see if row is visible */
- row = get_row_from_tree_path (tree_view, path);
-
- /*
- * A row insert is not necessarily visible. For example,
- * a row can be draged & dropped into another row, which
- * causes an insert on the model that isn't visible in the
- * view. Only generate a signal if the inserted row is
- * visible.
- */
- if (row != -1)
- {
- GtkTreeIter iter;
- gint n_cols, col;
-
- gtk_tree_model_get_iter (tree_model, &iter, path);
-
- /* Figure out number of visible children. */
- if (gtk_tree_model_iter_has_child (tree_model, &iter))
- {
- /*
- * By passing path into this function, we find the number of
- * visible children of path.
- */
- n_inserted = 0;
- iterate_thru_children (tree_view, tree_model,
- path, NULL, &n_inserted, 0);
-
- /* Must add one to include the row that is being added */
- n_inserted++;
- }
- else
- n_inserted = 1;
-
- /* Set rows below the inserted row to ATK_STATE_STALE */
- traverse_cells (gailview, path, TRUE, TRUE);
-
- /* Generate row-inserted signal */
- g_signal_emit_by_name (atk_obj, "row_inserted", row, n_inserted);
-
- /* Generate children-changed signals */
- n_cols = gail_tree_view_get_n_columns (ATK_TABLE (atk_obj));
- for (child_row = row; child_row < (row + n_inserted); child_row++)
- {
- for (col = 0; col < n_cols; col++)
- {
- /*
- * Pass NULL as the child object, i.e. 4th argument
- */
- g_signal_emit_by_name (atk_obj, "children_changed::add",
- ((row * n_cols) + col), NULL, NULL);
- }
- }
- }
- else
- {
- /*
- * The row has been inserted inside another row. This can
- * cause a row that previously couldn't be expanded to now
- * be expandable.
- */
- path_copy = gtk_tree_path_copy (path);
- gtk_tree_path_up (path_copy);
- set_expand_state (tree_view, tree_model, gailview, path_copy, TRUE);
- gtk_tree_path_free (path_copy);
- }
-}
-
-static void
-model_row_deleted (GtkTreeModel *tree_model,
- GtkTreePath *path,
- gpointer user_data)
-{
- GtkTreeView *tree_view;
- GtkTreePath *path_copy;
- AtkObject *atk_obj;
- GailTreeView *gailview;
- gint row, col, n_cols;
-
- tree_view = (GtkTreeView *)user_data;
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
- gailview = GAIL_TREE_VIEW (atk_obj);
-
- if (gailview->idle_expand_id)
- {
- g_source_remove (gailview->idle_expand_id);
- gtk_tree_path_free (gailview->idle_expand_path);
- gailview->idle_expand_id = 0;
- }
- /* Check to see if row is visible */
- clean_rows (gailview);
-
- /* Set rows at or below the specified row to ATK_STATE_STALE */
- traverse_cells (gailview, path, TRUE, TRUE);
-
- /*
- * If deleting a row with a depth > 1, then this may affect the
- * expansion/contraction of its parent(s). Make sure this is
- * handled.
- */
- if (gtk_tree_path_get_depth (path) > 1)
- {
- path_copy = gtk_tree_path_copy (path);
- gtk_tree_path_up (path_copy);
- set_expand_state (tree_view, tree_model, gailview, path_copy, TRUE);
- gtk_tree_path_free (path_copy);
- }
- row = get_row_from_tree_path (tree_view, path);
- /*
- * If the row which is deleted is not visible because it is a child of
- * a collapsed row then row will be -1
- */
- if (row > 0)
- g_signal_emit_by_name (atk_obj, "row_deleted", row,
- gailview->n_children_deleted + 1);
- gailview->n_children_deleted = 0;
-
- /* Generate children-changed signals */
- n_cols = get_n_actual_columns (tree_view);
- for (col = 0; col < n_cols; col++)
- {
- /*
- * Pass NULL as the child object, 4th argument.
- */
- g_signal_emit_by_name (atk_obj, "children_changed::remove",
- ((row * n_cols) + col), NULL, NULL);
- }
-}
-
-/*
- * This function gets called when a row is deleted or when rows are
- * removed from the view due to a collapse event. Note that the
- * count is the number of visible *children* of the deleted row,
- * so it does not include the row being deleted.
- *
- * As this function is called before the rows are removed we just note the
- * number of rows and then deal with it when we get a notification that
- * rows were deleted or collapsed.
- */
-static void
-destroy_count_func (GtkTreeView *tree_view,
- GtkTreePath *path,
- gint count,
- gpointer user_data)
-{
- AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
- GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
-
- gail_return_if_fail (gailview->n_children_deleted == 0);
- gailview->n_children_deleted = count;
-}
-
-static void
-model_rows_reordered (GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gint *new_order,
- gpointer user_data)
-{
- GtkTreeView *tree_view = (GtkTreeView *)user_data;
- AtkObject *atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
- GailTreeView *gailview = GAIL_TREE_VIEW (atk_obj);
-
- if (gailview->idle_expand_id)
- {
- g_source_remove (gailview->idle_expand_id);
- gtk_tree_path_free (gailview->idle_expand_path);
- gailview->idle_expand_id = 0;
- }
- traverse_cells (gailview, NULL, TRUE, FALSE);
-
- g_signal_emit_by_name (atk_obj, "row_reordered");
-}
-
-static void
-adjustment_changed (GtkAdjustment *adjustment,
- GtkTreeView *tree_view)
-{
- AtkObject *atk_obj;
- GailTreeView* obj;
-
- /*
- * The scrollbars have changed
- */
- atk_obj = gtk_widget_get_accessible (GTK_WIDGET (tree_view));
- obj = GAIL_TREE_VIEW (atk_obj);
-
- traverse_cells (obj, NULL, FALSE, FALSE);
-}
-
-static void
-set_cell_visibility (GtkTreeView *tree_view,
- GailCell *cell,
- GtkTreeViewColumn *tv_col,
- GtkTreePath *tree_path,
- gboolean emit_signal)
-{
- GdkRectangle cell_rect;
-
- /* Get these three values in tree coords */
- if (gtk_widget_get_realized (GTK_WIDGET (tree_view)))
- gtk_tree_view_get_cell_area (tree_view, tree_path, tv_col, &cell_rect);
- else
- cell_rect.height = 0;
-
- if (cell_rect.height > 0)
- {
- /*
- * The height will be zero for a cell for which an antecedent is not
- * expanded
- */
- gail_cell_add_state (cell, ATK_STATE_VISIBLE, emit_signal);
- if (is_cell_showing (tree_view, &cell_rect))
- gail_cell_add_state (cell, ATK_STATE_SHOWING, emit_signal);
- else
- gail_cell_remove_state (cell, ATK_STATE_SHOWING, emit_signal);
- }
- else
- {
- gail_cell_remove_state (cell, ATK_STATE_VISIBLE, emit_signal);
- gail_cell_remove_state (cell, ATK_STATE_SHOWING, emit_signal);
- }
-}
-
-static gboolean
-is_cell_showing (GtkTreeView *tree_view,
- GdkRectangle *cell_rect)
-{
- GdkRectangle rect, *visible_rect;
- GdkRectangle rect1, *tree_cell_rect;
- gint bx, by;
- gboolean is_showing;
- /*
- * A cell is considered "SHOWING" if any part of the cell is in the visible
- * area. Other ways we could do this is by a cell's midpoint or if the cell
- * is fully in the visible range. Since we have the cell_rect x,y,width,height
- * of the cell, any of these is easy to compute.
- *
- * It is assumed that cell's rectangle is in widget coordinates so we
- * must transform to tree cordinates.
- */
- visible_rect = ▭
- tree_cell_rect = &rect1;
- tree_cell_rect->x = cell_rect->x;
- tree_cell_rect->y = cell_rect->y;
- tree_cell_rect->width = cell_rect->width;
- tree_cell_rect->height = cell_rect->height;
-
- gtk_tree_view_get_visible_rect (tree_view, visible_rect);
- gtk_tree_view_convert_tree_to_bin_window_coords (tree_view, visible_rect->x,
- visible_rect->y, &bx, &by);
-
- if (((tree_cell_rect->x + tree_cell_rect->width) < bx) ||
- ((tree_cell_rect->y + tree_cell_rect->height) < by) ||
- (tree_cell_rect->x > (bx + visible_rect->width)) ||
- (tree_cell_rect->y > (by + visible_rect->height)))
- is_showing = FALSE;
- else
- is_showing = TRUE;
-
- return is_showing;
-}
-
-/* Misc Public */
-
-/*
- * This function is called when a cell's flyweight is created in
- * gail_tree_view_table_ref_at with emit_change_signal set to FALSE
- * and in model_row_changed() on receipt of "row-changed" signal when
- * emit_change_signal is set to TRUE
- */
-static gboolean
-update_cell_value (GailRendererCell *renderer_cell,
- GailTreeView *gailview,
- gboolean emit_change_signal)
-{
- GailTreeViewCellInfo *cell_info;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
- GtkTreePath *path;
- GtkTreeIter iter;
- GList *renderers, *cur_renderer;
- GParamSpec *spec;
- GailRendererCellClass *gail_renderer_cell_class;
- GtkCellRendererClass *gtk_cell_renderer_class;
- GailCell *cell;
- gchar **prop_list;
- AtkObject *parent;
- gboolean is_expander, is_expanded;
-
- gail_renderer_cell_class = GAIL_RENDERER_CELL_GET_CLASS (renderer_cell);
- if (renderer_cell->renderer)
- gtk_cell_renderer_class = GTK_CELL_RENDERER_GET_CLASS (renderer_cell->renderer);
- else
- gtk_cell_renderer_class = NULL;
-
- prop_list = gail_renderer_cell_class->property_list;
-
- cell = GAIL_CELL (renderer_cell);
- cell_info = find_cell_info (gailview, cell, NULL, TRUE);
- gail_return_val_if_fail (cell_info, FALSE);
- gail_return_val_if_fail (cell_info->cell_col_ref, FALSE);
- gail_return_val_if_fail (cell_info->cell_row_ref, FALSE);
-
- if (emit_change_signal && cell_info->in_use)
- {
- tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (gailview)));
- tree_model = gtk_tree_view_get_model (tree_view);
- path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- if (path == NULL)
- return FALSE;
-
- gtk_tree_model_get_iter (tree_model, &iter, path);
- is_expander = FALSE;
- is_expanded = FALSE;
- if (gtk_tree_model_iter_has_child (tree_model, &iter))
- {
- GtkTreeViewColumn *expander_tv;
-
- expander_tv = gtk_tree_view_get_expander_column (tree_view);
- if (expander_tv == cell_info->cell_col_ref)
- {
- is_expander = TRUE;
- is_expanded = gtk_tree_view_row_expanded (tree_view, path);
- }
- }
- gtk_tree_path_free (path);
- gtk_tree_view_column_cell_set_cell_data (cell_info->cell_col_ref,
- tree_model, &iter, is_expander, is_expanded);
- }
- renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cell_info->cell_col_ref));
- gail_return_val_if_fail (renderers, FALSE);
-
- /*
- * If the cell is in a container, its index is used to find the renderer
- * in the list
- */
-
- /*
- * Otherwise, we assume that the cell is represented by the first renderer
- * in the list
- */
-
- if (cell_info->in_use) {
- parent = atk_object_get_parent (ATK_OBJECT (cell));
- if (!ATK_IS_OBJECT (cell)) g_on_error_query (NULL);
- if (GAIL_IS_CONTAINER_CELL (parent))
- cur_renderer = g_list_nth (renderers, cell->index);
- else
- cur_renderer = renderers;
- }
- else {
- return FALSE;
- }
-
- gail_return_val_if_fail (cur_renderer != NULL, FALSE);
-
- if (gtk_cell_renderer_class)
- {
- while (*prop_list)
- {
- spec = g_object_class_find_property
- (G_OBJECT_CLASS (gtk_cell_renderer_class), *prop_list);
-
- if (spec != NULL)
- {
- GValue value = { 0, };
-
- g_value_init (&value, spec->value_type);
- g_object_get_property (cur_renderer->data, *prop_list, &value);
- g_object_set_property (G_OBJECT (renderer_cell->renderer),
- *prop_list, &value);
- g_value_unset(&value);
- }
- else
- g_warning ("Invalid property: %s\n", *prop_list);
- prop_list++;
- }
- }
- g_list_free (renderers);
- return gail_renderer_cell_update_cache (renderer_cell, emit_change_signal);
-}
-
-static void
-set_iter_nth_row (GtkTreeView *tree_view,
- GtkTreeIter *iter,
- gint row)
-{
- GtkTreeModel *tree_model;
-
- tree_model = gtk_tree_view_get_model (tree_view);
- gtk_tree_model_get_iter_first (tree_model, iter);
- iter = return_iter_nth_row (tree_view, tree_model, iter, 0 , row);
-}
-
-static gint
-get_row_from_tree_path (GtkTreeView *tree_view,
- GtkTreePath *path)
-{
- GtkTreeModel *tree_model;
- GtkTreePath *root_tree;
- gint row;
-
- tree_model = gtk_tree_view_get_model (tree_view);
-
- if (gtk_tree_model_get_flags (tree_model) & GTK_TREE_MODEL_LIST_ONLY)
- row = gtk_tree_path_get_indices (path)[0];
- else
- {
- root_tree = gtk_tree_path_new_first ();
- row = 0;
- iterate_thru_children (tree_view, tree_model, root_tree, path, &row, 0);
- gtk_tree_path_free (root_tree);
- }
-
- return row;
-}
-
-/* Misc Private */
-
-/*
- * Get the specified GtkTreeViewColumn in the GtkTreeView.
- * Only visible columns are considered.
- */
-static GtkTreeViewColumn*
-get_column (GtkTreeView *tree_view,
- gint in_col)
-{
- GtkTreeViewColumn *tv_col;
- gint n_cols = -1;
- gint i = 0;
-
- if (in_col < 0)
- {
- g_warning ("Request for invalid column %d\n", in_col);
- return NULL;
- }
-
- tv_col = gtk_tree_view_get_column (tree_view, i);
-
- while (tv_col != NULL)
- {
- if (gtk_tree_view_column_get_visible (tv_col))
- n_cols++;
- if (in_col == n_cols)
- break;
- tv_col = gtk_tree_view_get_column (tree_view, ++i);
- }
-
- if (in_col != n_cols)
- {
- g_warning ("Request for invalid column %d\n", in_col);
- return NULL;
- }
- return tv_col;
-}
-
-static gint
-get_actual_column_number (GtkTreeView *tree_view,
- gint visible_column)
-{
- GtkTreeViewColumn *tv_col;
- gint actual_column = 0;
- gint visible_columns = -1;
- /*
- * This function calculates the column number which corresponds to the
- * specified visible column number
- */
- tv_col = gtk_tree_view_get_column (tree_view, actual_column);
-
- while (tv_col != NULL)
- {
- if (gtk_tree_view_column_get_visible (tv_col))
- visible_columns++;
- if (visible_columns == visible_column)
- return actual_column;
- tv_col = gtk_tree_view_get_column (tree_view, ++actual_column);
- }
- g_warning ("get_actual_column_number failed for %d\n", visible_column);
- return -1;
-}
-
-static gint
-get_visible_column_number (GtkTreeView *tree_view,
- gint actual_column)
-{
- GtkTreeViewColumn *tv_col;
- gint column = 0;
- gint visible_columns = -1;
- /*
- * This function calculates the visible column number which corresponds to the
- * specified actual column number
- */
- tv_col = gtk_tree_view_get_column (tree_view, column);
-
- while (tv_col != NULL)
- {
- if (gtk_tree_view_column_get_visible (tv_col))
- {
- visible_columns++;
- if (actual_column == column)
- return visible_columns;
- }
- else
- if (actual_column == column)
- return -1;
- tv_col = gtk_tree_view_get_column (tree_view, ++column);
- }
- g_warning ("get_visible_column_number failed for %d\n", actual_column);
- return -1;
-}
-
-/**
- * Helper recursive function that returns GtkTreeIter pointer to nth row.
- **/
-static GtkTreeIter*
-return_iter_nth_row(GtkTreeView *tree_view,
- GtkTreeModel *tree_model,
- GtkTreeIter *iter,
- gint increment,
- gint row)
-{
- GtkTreePath *current_path = gtk_tree_model_get_path (tree_model, iter);
- GtkTreeIter new_iter;
- gboolean row_expanded;
-
- if (increment == row) {
- gtk_tree_path_free (current_path);
- return iter;
- }
-
- row_expanded = gtk_tree_view_row_expanded (tree_view, current_path);
- gtk_tree_path_free (current_path);
-
- new_iter = *iter;
- if ((row_expanded && gtk_tree_model_iter_children (tree_model, iter, &new_iter)) ||
- (gtk_tree_model_iter_next (tree_model, iter)) ||
- (gtk_tree_model_iter_parent (tree_model, iter, &new_iter) &&
- (gtk_tree_model_iter_next (tree_model, iter))))
- return return_iter_nth_row (tree_view, tree_model, iter,
- ++increment, row);
-
- return NULL;
-}
-
-/**
- * Recursively called until the row specified by orig is found.
- *
- * *count will be set to the visible row number of the child
- * relative to the row that was initially passed in as tree_path.
- *
- * *count will be -1 if orig is not found as a child (a row that is
- * not visible will not be found, e.g. if the row is inside a
- * collapsed row). If NULL is passed in as orig, *count will
- * be a count of the visible children.
- *
- * NOTE: the value for depth must be 0 when this recursive function
- * is initially called, or it may not function as expected.
- **/
-static void
-iterate_thru_children(GtkTreeView *tree_view,
- GtkTreeModel *tree_model,
- GtkTreePath *tree_path,
- GtkTreePath *orig,
- gint *count,
- gint depth)
-{
- GtkTreeIter iter;
-
- if (!gtk_tree_model_get_iter (tree_model, &iter, tree_path))
- return;
-
- if (tree_path && orig && !gtk_tree_path_compare (tree_path, orig))
- /* Found it! */
- return;
-
- if (tree_path && orig && gtk_tree_path_compare (tree_path, orig) > 0)
- {
- /* Past it, so return -1 */
- *count = -1;
- return;
- }
- else if (gtk_tree_view_row_expanded (tree_view, tree_path) &&
- gtk_tree_model_iter_has_child (tree_model, &iter))
- {
- (*count)++;
- gtk_tree_path_append_index (tree_path, 0);
- iterate_thru_children (tree_view, tree_model, tree_path,
- orig, count, (depth + 1));
- return;
- }
- else if (gtk_tree_model_iter_next (tree_model, &iter))
- {
- (*count)++;
- tree_path = gtk_tree_model_get_path (tree_model, &iter);
- if (tree_path)
- {
- iterate_thru_children (tree_view, tree_model, tree_path,
- orig, count, depth);
- gtk_tree_path_free (tree_path);
- }
- return;
- }
- else if (gtk_tree_path_up (tree_path))
- {
- GtkTreeIter temp_iter;
- gboolean exit_loop = FALSE;
- gint new_depth = depth - 1;
-
- (*count)++;
-
- /*
- * Make sure that we back up until we find a row
- * where gtk_tree_path_next does not return NULL.
- */
- while (!exit_loop)
- {
- if (gtk_tree_path_get_depth (tree_path) == 0)
- /* depth is now zero so */
- return;
- gtk_tree_path_next (tree_path);
-
- /* Verify that the next row is a valid row! */
- exit_loop = gtk_tree_model_get_iter (tree_model, &temp_iter, tree_path);
-
- if (!exit_loop)
- {
- /* Keep going up until we find a row that has a valid next */
- if (gtk_tree_path_get_depth(tree_path) > 1)
- {
- new_depth--;
- gtk_tree_path_up (tree_path);
- }
- else
- {
- /*
- * If depth is 1 and gtk_tree_model_get_iter returns FALSE,
- * then we are at the last row, so just return.
- */
- if (orig != NULL)
- *count = -1;
-
- return;
- }
- }
- }
-
- /*
- * This guarantees that we will stop when we hit the end of the
- * children.
- */
- if (new_depth < 0)
- return;
-
- iterate_thru_children (tree_view, tree_model, tree_path,
- orig, count, new_depth);
- return;
- }
-
- /*
- * If it gets here, then the path wasn't found. Situations
- * that would cause this would be if the path passed in is
- * invalid or contained within the last row, but not visible
- * because the last row is not expanded. If NULL was passed
- * in then a row count is desired, so only set count to -1
- * if orig is not NULL.
- */
- if (orig != NULL)
- *count = -1;
-
- return;
-}
-
-static void
-clean_cell_info (GailTreeView *gailview,
- GList *list)
-{
- GailTreeViewCellInfo *cell_info;
- GObject *obj;
-
- g_assert (GAIL_IS_TREE_VIEW (gailview));
-
- cell_info = list->data;
-
- if (cell_info->in_use) {
- obj = G_OBJECT (cell_info->cell);
-
- gail_cell_add_state (cell_info->cell, ATK_STATE_DEFUNCT, FALSE);
- g_object_weak_unref (obj, (GWeakNotify) cell_destroyed, cell_info);
- cell_info->in_use = FALSE;
- if (!gailview->garbage_collection_pending) {
- gailview->garbage_collection_pending = TRUE;
- g_assert (gailview->idle_garbage_collect_id == 0);
- gailview->idle_garbage_collect_id =
- gdk_threads_add_idle (idle_garbage_collect_cell_data, gailview);
- }
- }
-}
-
-static void
-clean_rows (GailTreeView *gailview)
-{
- GArray *array;
-
- /* Clean GailTreeViewRowInfo data */
-
- array = gailview->row_data;
- if (array != NULL)
- {
- GailTreeViewRowInfo *row_info;
- GtkTreePath *row_path;
- gint i;
-
- /*
- * Loop backwards so that calls to free_row_info
- * do not affect the index numbers
- */
- for (i = (array->len - 1); i >= 0; i --)
- {
- row_info = g_array_index (array, GailTreeViewRowInfo*, i);
- row_path = gtk_tree_row_reference_get_path (row_info->row_ref);
-
- /* Remove any rows that have become invalid */
- if (row_path == NULL)
- free_row_info (array, i, TRUE);
- else
- gtk_tree_path_free (row_path);
- }
- }
-
- /* Clean GailTreeViewCellInfo data */
-
- if (gailview->cell_data != NULL)
- {
- GailTreeViewCellInfo *cell_info;
- GtkTreePath *row_path;
- GList *cur_list;
- GList *temp_list;
-
- temp_list = gailview->cell_data;
-
- /* Must loop through them all */
- while (temp_list != NULL)
- {
- cur_list = temp_list;
- cell_info = temp_list->data;
- temp_list = temp_list->next;
- row_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
-
- /*
- * If the cell has become invalid because the row has been removed,
- * then set the cell's state to ATK_STATE_DEFUNCT and remove the cell
- * from gailview->cell_data. If row_path is NULL then the row has
- * been removed.
- */
- if (row_path == NULL)
- {
- clean_cell_info (gailview, cur_list);
- }
- else
- {
- gtk_tree_path_free (row_path);
- }
- }
- }
-}
-
-static void
-clean_cols (GailTreeView *gailview,
- GtkTreeViewColumn *tv_col)
-{
- /* Clean GailTreeViewCellInfo data */
-
- if (gailview->cell_data != NULL)
- {
- GailTreeViewCellInfo *cell_info;
- GList *cur_list, *temp_list;
-
- temp_list = gailview->cell_data;
-
- while (temp_list != NULL)
- {
- cur_list = temp_list;
- cell_info = temp_list->data;
- temp_list = temp_list->next;
-
- /*
- * If the cell has become invalid because the column tv_col
- * has been removed, then set the cell's state to ATK_STATE_DEFUNCT
- * and remove the cell from gailview->cell_data.
- */
- if (cell_info->cell_col_ref == tv_col)
- {
- clean_cell_info (gailview, cur_list);
- }
- }
- }
-}
-
-static gboolean
-idle_garbage_collect_cell_data (gpointer data)
-{
- GailTreeView *tree_view;
-
- g_assert (GAIL_IS_TREE_VIEW (data));
- tree_view = (GailTreeView *)data;
-
- /* this is the idle handler (only one instance allowed), so
- * we can safely delete it.
- */
- tree_view->garbage_collection_pending = FALSE;
- tree_view->idle_garbage_collect_id = 0;
-
- tree_view->garbage_collection_pending = garbage_collect_cell_data (data);
-
- /* N.B.: if for some reason another handler has re-enterantly been queued
- * while this handler was being serviced, it has its own gsource, therefore this handler
- * should always return FALSE.
- */
- return FALSE;
-}
-
-static gboolean
-garbage_collect_cell_data (gpointer data)
-{
- GailTreeView *tree_view;
- GList *temp_list, *list;
- GailTreeViewCellInfo *cell_info;
-
- g_assert (GAIL_IS_TREE_VIEW (data));
- tree_view = (GailTreeView *)data;
- list = g_list_copy (tree_view->cell_data);
-
- tree_view->garbage_collection_pending = FALSE;
- if (tree_view->idle_garbage_collect_id != 0)
- {
- g_source_remove (tree_view->idle_garbage_collect_id);
- tree_view->idle_garbage_collect_id = 0;
- }
-
- /* Must loop through them all */
- temp_list = list;
- while (temp_list != NULL)
- {
- cell_info = temp_list->data;
- if (!cell_info->in_use)
- {
- /* g_object_unref (cell_info->cell); */
- tree_view->cell_data = g_list_remove (tree_view->cell_data,
- cell_info);
- if (cell_info->cell_row_ref)
- gtk_tree_row_reference_free (cell_info->cell_row_ref);
- g_free (cell_info);
- }
- temp_list = temp_list->next;
- }
- g_list_free (list);
-
- return tree_view->garbage_collection_pending;
-}
-
-/**
- * If tree_path is passed in as NULL, then all cells are acted on.
- * Otherwise, just act on those cells that are on a row greater than
- * the specified tree_path. If inc_row is passed in as TRUE, then rows
- * greater and equal to the specified tree_path are acted on.
- *
- * if set_stale is set the ATK_STATE_STALE is set on cells which are to be
- * acted on.
- *
- * The function set_cell_visibility() is called on all cells to be
- * acted on to update the visibility of the cell.
- **/
-static void
-traverse_cells (GailTreeView *tree_view,
- GtkTreePath *tree_path,
- gboolean set_stale,
- gboolean inc_row)
-{
- if (tree_view->cell_data != NULL)
- {
- GailTreeViewCellInfo *cell_info;
- GtkTreeView *gtk_tree_view;
- GList *temp_list;
- GtkWidget *widget;
-
- g_assert (GTK_IS_ACCESSIBLE (tree_view));
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (tree_view));
- if (!widget)
- /* Widget is being deleted */
- return;
-
- gtk_tree_view = GTK_TREE_VIEW (widget);
- temp_list = tree_view->cell_data;
-
- /* Must loop through them all */
- while (temp_list != NULL)
- {
- GtkTreePath *row_path;
- gboolean act_on_cell;
-
- cell_info = temp_list->data;
- temp_list = temp_list->next;
-
- if (cell_info->in_use)
- {
- row_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- g_return_if_fail (row_path != NULL);
- if (tree_path == NULL)
- act_on_cell = TRUE;
- else
- {
- gint comparison;
-
- comparison = gtk_tree_path_compare (row_path, tree_path);
- if ((comparison > 0) ||
- (comparison == 0 && inc_row))
- act_on_cell = TRUE;
- else
- act_on_cell = FALSE;
- }
- if (!cell_info->in_use) g_warning ("warning: cell info destroyed during traversal");
- if (act_on_cell && cell_info->in_use)
- {
- if (set_stale)
- gail_cell_add_state (cell_info->cell, ATK_STATE_STALE, TRUE);
- set_cell_visibility (gtk_tree_view,
- cell_info->cell,
- cell_info->cell_col_ref,
- row_path, TRUE);
- }
- gtk_tree_path_free (row_path);
- }
- }
- }
- g_signal_emit_by_name (tree_view, "visible-data-changed");
-}
-
-static void
-free_row_info (GArray *array,
- gint array_idx,
- gboolean shift)
-{
- GailTreeViewRowInfo* obj;
-
- obj = g_array_index (array, GailTreeViewRowInfo*, array_idx);
-
- g_free (obj->description);
- if (obj->row_ref != NULL)
- gtk_tree_row_reference_free (obj->row_ref);
- if (obj->header)
- g_object_unref (obj->header);
- g_free (obj);
-
- if (shift)
- g_array_remove_index (array, array_idx);
-}
-
-/*
- * If the tree_path passed in has children, then
- * ATK_STATE_EXPANDABLE is set. If the row is expanded
- * ATK_STATE_EXPANDED is turned on. If the row is
- * collapsed, then ATK_STATE_EXPANDED is removed.
- *
- * If the tree_path passed in has no children, then
- * ATK_STATE_EXPANDABLE and ATK_STATE_EXPANDED are removed.
- *
- * If set_on_ancestor is TRUE, then this function will also
- * update all cells that are ancestors of the tree_path.
- */
-static void
-set_expand_state (GtkTreeView *tree_view,
- GtkTreeModel *tree_model,
- GailTreeView *gailview,
- GtkTreePath *tree_path,
- gboolean set_on_ancestor)
-{
- if (gailview->cell_data != NULL)
- {
- GtkTreeViewColumn *expander_tv;
- GailTreeViewCellInfo *cell_info;
- GList *temp_list;
- GtkTreePath *cell_path;
- GtkTreeIter iter;
- gboolean found;
-
- temp_list = gailview->cell_data;
-
- while (temp_list != NULL)
- {
- cell_info = temp_list->data;
- temp_list = temp_list->next;
- if (cell_info->in_use)
- {
- cell_path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- found = FALSE;
-
- if (cell_path != NULL)
- {
- GailCell *cell = GAIL_CELL (cell_info->cell);
-
- expander_tv = gtk_tree_view_get_expander_column (tree_view);
-
- /*
- * Only set state for the cell that is in the column with the
- * expander toggle
- */
- if (expander_tv == cell_info->cell_col_ref)
- {
- if (tree_path && gtk_tree_path_compare (cell_path, tree_path) == 0)
- found = TRUE;
- else if (set_on_ancestor &&
- gtk_tree_path_get_depth (cell_path) <
- gtk_tree_path_get_depth (tree_path) &&
- gtk_tree_path_is_ancestor (cell_path, tree_path) == 1)
- /* Only set if set_on_ancestor was passed in as TRUE */
- found = TRUE;
- }
-
- /*
- * Set ATK_STATE_EXPANDABLE and ATK_STATE_EXPANDED
- * for ancestors and found cells.
- */
- if (found)
- {
- /*
- * Must check against cell_path since cell_path
- * can be equal to or an ancestor of tree_path.
- */
- gtk_tree_model_get_iter (tree_model, &iter, cell_path);
-
- /* Set or unset ATK_STATE_EXPANDABLE as appropriate */
- if (gtk_tree_model_iter_has_child (tree_model, &iter))
- {
- set_cell_expandable (cell);
-
- if (gtk_tree_view_row_expanded (tree_view, cell_path))
- gail_cell_add_state (cell, ATK_STATE_EXPANDED, TRUE);
- else
- gail_cell_remove_state (cell,
- ATK_STATE_EXPANDED, TRUE);
- }
- else
- {
- gail_cell_remove_state (cell,
- ATK_STATE_EXPANDED, TRUE);
- if (gail_cell_remove_state (cell,
- ATK_STATE_EXPANDABLE, TRUE))
- /* The state may have been propagated to the container cell */
- if (!GAIL_IS_CONTAINER_CELL (cell))
- gail_cell_remove_action_by_name (cell,
- "expand or contract");
- }
-
- /*
- * We assume that each cell in the cache once and
- * a container cell is before its child cells so we are
- * finished if set_on_ancestor is not set to TRUE.
- */
- if (!set_on_ancestor)
- break;
- }
- }
- gtk_tree_path_free (cell_path);
- }
- }
- }
-}
-
-
-static void
-add_cell_actions (GailCell *cell,
- gboolean editable)
-{
- if (GAIL_IS_BOOLEAN_CELL (cell))
- gail_cell_add_action (cell,
- "toggle",
- "toggles the cell", /* action description */
- NULL,
- toggle_cell_toggled);
- if (editable)
- gail_cell_add_action (cell,
- "edit",
- "creates a widget in which the contents of the cell can be edited",
- NULL,
- edit_cell);
- gail_cell_add_action (cell,
- "activate",
- "activate the cell",
- NULL,
- activate_cell);
-}
-
-static void
-toggle_cell_expanded (GailCell *cell)
-{
- GailTreeViewCellInfo *cell_info;
- GtkTreeView *tree_view;
- GtkTreePath *path;
- AtkObject *parent;
- AtkStateSet *stateset;
-
- parent = atk_object_get_parent (ATK_OBJECT (cell));
- if (GAIL_IS_CONTAINER_CELL (parent))
- parent = atk_object_get_parent (parent);
-
- cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
- gail_return_if_fail (cell_info);
- gail_return_if_fail (cell_info->cell_col_ref);
- gail_return_if_fail (cell_info->cell_row_ref);
-
- tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)));
- path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- gail_return_if_fail (path);
-
- stateset = atk_object_ref_state_set (ATK_OBJECT (cell));
- if (atk_state_set_contains_state (stateset, ATK_STATE_EXPANDED))
- gtk_tree_view_collapse_row (tree_view, path);
- else
- gtk_tree_view_expand_row (tree_view, path, TRUE);
- g_object_unref (stateset);
- gtk_tree_path_free (path);
- return;
-}
-
-static void
-toggle_cell_toggled (GailCell *cell)
-{
- GailTreeViewCellInfo *cell_info;
- GtkTreePath *path;
- gchar *pathstring;
- GList *renderers, *cur_renderer;
- AtkObject *parent;
- gboolean is_container_cell = FALSE;
-
- parent = atk_object_get_parent (ATK_OBJECT (cell));
- if (GAIL_IS_CONTAINER_CELL (parent))
- {
- is_container_cell = TRUE;
- parent = atk_object_get_parent (parent);
- }
-
- cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
- gail_return_if_fail (cell_info);
- gail_return_if_fail (cell_info->cell_col_ref);
- gail_return_if_fail (cell_info->cell_row_ref);
-
- path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- gail_return_if_fail (path);
- pathstring = gtk_tree_path_to_string (path);
-
- renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cell_info->cell_col_ref));
- gail_return_if_fail (renderers);
-
- /*
- * if the cell is in a container, its index is used to find the
- * renderer in the list
- */
-
- if (is_container_cell)
- cur_renderer = g_list_nth (renderers, cell->index);
- else
- /*
- * Otherwise, we assume that the cell is represented by the first
- * renderer in the list
- */
- cur_renderer = renderers;
-
- gail_return_if_fail (cur_renderer);
-
- g_signal_emit_by_name (cur_renderer->data, "toggled", pathstring);
- g_list_free (renderers);
- g_free (pathstring);
- gtk_tree_path_free (path);
- return;
-}
-
-static void
-edit_cell (GailCell *cell)
-{
- GailTreeViewCellInfo *cell_info;
- GtkTreeView *tree_view;
- GtkTreePath *path;
- AtkObject *parent;
-
- editing = TRUE;
- parent = atk_object_get_parent (ATK_OBJECT (cell));
- if (GAIL_IS_CONTAINER_CELL (parent))
- parent = atk_object_get_parent (parent);
-
- cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
- gail_return_if_fail (cell_info);
- gail_return_if_fail (cell_info->cell_col_ref);
- gail_return_if_fail (cell_info->cell_row_ref);
-
- tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)));
- path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- gail_return_if_fail (path);
- gtk_tree_view_set_cursor (tree_view, path, cell_info->cell_col_ref, TRUE);
- gtk_tree_path_free (path);
- return;
-}
-
-static void
-activate_cell (GailCell *cell)
-{
- GailTreeViewCellInfo *cell_info;
- GtkTreeView *tree_view;
- GtkTreePath *path;
- AtkObject *parent;
-
- editing = TRUE;
- parent = atk_object_get_parent (ATK_OBJECT (cell));
- if (GAIL_IS_CONTAINER_CELL (parent))
- parent = atk_object_get_parent (parent);
-
- cell_info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
- gail_return_if_fail (cell_info);
- gail_return_if_fail (cell_info->cell_col_ref);
- gail_return_if_fail (cell_info->cell_row_ref);
-
- tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)));
- path = gtk_tree_row_reference_get_path (cell_info->cell_row_ref);
- gail_return_if_fail (path);
- gtk_tree_view_row_activated (tree_view, path, cell_info->cell_col_ref);
- gtk_tree_path_free (path);
- return;
-}
-
-static void
-cell_destroyed (gpointer data)
-{
- GailTreeViewCellInfo *cell_info = data;
-
- gail_return_if_fail (cell_info);
- if (cell_info->in_use) {
- cell_info->in_use = FALSE;
-
- g_assert (GAIL_IS_TREE_VIEW (cell_info->view));
- if (!cell_info->view->garbage_collection_pending) {
- cell_info->view->garbage_collection_pending = TRUE;
- cell_info->view->idle_garbage_collect_id =
- gdk_threads_add_idle (idle_garbage_collect_cell_data, cell_info->view);
- }
- }
-}
-
-#if 0
-static void
-cell_info_remove (GailTreeView *tree_view,
- GailCell *cell)
-{
- GailTreeViewCellInfo *info;
- GList *temp_list;
-
- info = find_cell_info (tree_view, cell, &temp_list, FALSE);
- if (info)
- {
- info->in_use = FALSE;
- return;
- }
- g_warning ("No cell removed in cell_info_remove\n");
-}
-#endif
-
-static void
-cell_info_get_index (GtkTreeView *tree_view,
- GailTreeViewCellInfo *info,
- gint *index)
-{
- GtkTreePath *path;
- gint column_number;
-
- path = gtk_tree_row_reference_get_path (info->cell_row_ref);
- gail_return_if_fail (path);
-
- column_number = get_column_number (tree_view, info->cell_col_ref, FALSE);
- *index = get_index (tree_view, path, column_number);
- gtk_tree_path_free (path);
-}
-
-static void
-cell_info_new (GailTreeView *gailview,
- GtkTreeModel *tree_model,
- GtkTreePath *path,
- GtkTreeViewColumn *tv_col,
- GailCell *cell )
-{
- GailTreeViewCellInfo *cell_info;
-
- g_assert (GAIL_IS_TREE_VIEW (gailview));
-
- cell_info = g_new (GailTreeViewCellInfo, 1);
- cell_info->cell_row_ref = gtk_tree_row_reference_new (tree_model, path);
-
- cell_info->cell_col_ref = tv_col;
- cell_info->cell = cell;
- cell_info->in_use = TRUE; /* if we've created it, assume it's in use */
- cell_info->view = gailview;
- gailview->cell_data = g_list_append (gailview->cell_data, cell_info);
-
- /* Setup weak reference notification */
-
- g_object_weak_ref (G_OBJECT (cell),
- (GWeakNotify) cell_destroyed,
- cell_info);
-}
-
-static GailCell*
-find_cell (GailTreeView *gailview,
- gint index)
-{
- GailTreeViewCellInfo *info;
- GtkTreeView *tree_view;
- GList *cell_list;
- GList *l;
- gint real_index;
- gboolean needs_cleaning = FALSE;
- GailCell *retval = NULL;
-
- tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (gailview)));
- cell_list = gailview->cell_data;
-
- for (l = cell_list; l; l = l->next)
- {
- info = (GailTreeViewCellInfo *) (l->data);
- if (info->in_use)
- {
- cell_info_get_index (tree_view, info, &real_index);
- if (index == real_index)
- {
- retval = info->cell;
- break;
- }
- }
- else
- {
- needs_cleaning = TRUE;
- }
- }
- if (needs_cleaning)
- garbage_collect_cell_data (gailview);
-
- return retval;
-}
-
-static void
-refresh_cell_index (GailCell *cell)
-{
- GailTreeViewCellInfo *info;
- AtkObject *parent;
- GtkTreeView *tree_view;
- gint index;
-
- parent = atk_object_get_parent (ATK_OBJECT (cell));
- gail_return_if_fail (GAIL_IS_TREE_VIEW (parent));
-
- tree_view = GTK_TREE_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)));
-
- /* Find this cell in the GailTreeView's cache */
-
- info = find_cell_info (GAIL_TREE_VIEW (parent), cell, NULL, TRUE);
- gail_return_if_fail (info);
-
- cell_info_get_index (tree_view, info, &index);
- cell->index = index;
-}
-
-static void
-get_selected_rows (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- GPtrArray *array = (GPtrArray *)data;
-
- g_ptr_array_add (array, gtk_tree_path_copy (path));
-}
-
-static void
-connect_model_signals (GtkTreeView *view,
- GailTreeView *gailview)
-{
- GObject *obj;
-
- obj = G_OBJECT (gailview->tree_model);
- g_signal_connect_data (obj, "row-changed",
- (GCallback) model_row_changed, view, NULL, 0);
- g_signal_connect_data (obj, "row-inserted",
- (GCallback) model_row_inserted, view, NULL,
- G_CONNECT_AFTER);
- g_signal_connect_data (obj, "row-deleted",
- (GCallback) model_row_deleted, view, NULL,
- G_CONNECT_AFTER);
- g_signal_connect_data (obj, "rows-reordered",
- (GCallback) model_rows_reordered, view, NULL,
- G_CONNECT_AFTER);
-}
-
-static void
-disconnect_model_signals (GailTreeView *view)
-{
- GObject *obj;
- GtkWidget *widget;
-
- obj = G_OBJECT (view->tree_model);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (view));
- g_signal_handlers_disconnect_by_func (obj, (gpointer) model_row_changed, widget);
- g_signal_handlers_disconnect_by_func (obj, (gpointer) model_row_inserted, widget);
- g_signal_handlers_disconnect_by_func (obj, (gpointer) model_row_deleted, widget);
- g_signal_handlers_disconnect_by_func (obj, (gpointer) model_rows_reordered, widget);
-}
-
-static void
-clear_cached_data (GailTreeView *view)
-{
- GList *temp_list;
-
- if (view->row_data)
- {
- GArray *array = view->row_data;
- gint i;
-
- /*
- * Since the third argument to free_row_info is FALSE, we don't remove
- * the element. Therefore it is safe to loop forward.
- */
- for (i = 0; i < array->len; i++)
- free_row_info (array, i, FALSE);
-
- g_array_free (array, TRUE);
-
- view->row_data = NULL;
- }
-
- if (view->cell_data)
- {
- /* Must loop through them all */
- for (temp_list = view->cell_data; temp_list; temp_list = temp_list->next)
- {
- clean_cell_info (view, temp_list);
- }
- }
- garbage_collect_cell_data (view);
- if (view->cell_data)
- g_list_free (view->cell_data);
-
- view->cell_data = NULL;
-}
-
-/*
- * Returns the column number of the specified GtkTreeViewColumn
- *
- * If visible is set, the value returned will be the visible column number,
- * i.e. suitable for use in AtkTable function. If visible is not set, the
- * value returned is the actual column number, which is suitable for use in
- * getting an index value.
- */
-static gint
-get_column_number (GtkTreeView *tree_view,
- GtkTreeViewColumn *column,
- gboolean visible)
-{
- GList *temp_list, *column_list;
- GtkTreeViewColumn *tv_column;
- gint ret_val;
-
- column_list = gtk_tree_view_get_columns (tree_view);
- ret_val = 0;
- for (temp_list = column_list; temp_list; temp_list = temp_list->next)
- {
- tv_column = GTK_TREE_VIEW_COLUMN (temp_list->data);
- if (tv_column == column)
- break;
- if (!visible || gtk_tree_view_column_get_visible (tv_column))
- ret_val++;
- }
- if (temp_list == NULL)
- {
- ret_val = -1;
- }
- g_list_free (column_list);
- return ret_val;
-}
-
-static gint
-get_index (GtkTreeView *tree_view,
- GtkTreePath *path,
- gint actual_column)
-{
- gint depth = 0;
- gint index = 1;
- gint *indices = NULL;
-
-
- if (path)
- {
- depth = gtk_tree_path_get_depth (path);
- indices = gtk_tree_path_get_indices (path);
- }
-
- if (depth > 1)
- {
- GtkTreePath *copy_path;
- GtkTreeModel *model;
-
- model = gtk_tree_view_get_model (tree_view);
- copy_path = gtk_tree_path_copy (path);
- gtk_tree_path_up (copy_path);
- count_rows (model, NULL, copy_path, &index, 0, depth);
- gtk_tree_path_free (copy_path);
- }
-
- if (path)
- index += indices[depth-1];
- index *= get_n_actual_columns (tree_view);
- index += actual_column;
- return index;
-}
-
-/*
- * The function count_rows counts the number of rows starting at iter and ending
- * at end_path. The value of level is the depth of iter and the value of depth
- * is the depth of end_path. Rows at depth before end_path are counted.
- * This functions counts rows which are not visible because an ancestor is
- * collapsed.
- */
-static void
-count_rows (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreePath *end_path,
- gint *count,
- gint level,
- gint depth)
-{
- GtkTreeIter child_iter;
-
- if (!model) return;
-
- level++;
-
- *count += gtk_tree_model_iter_n_children (model, iter);
-
-#if 0
- g_print ("count_rows : %d level: %d depth: %d\n", *count, level, depth);
- if (iter != NULL)
- g_print ("path: %s\n",
- gtk_tree_path_to_string (gtk_tree_model_get_path (model, iter)));
-#endif
-
- if (level >= depth)
- return;
-
- if (gtk_tree_model_iter_children (model, &child_iter, iter))
- {
- gboolean ret_val = TRUE;
-
- while (ret_val)
- {
- if (level == depth - 1)
- {
- GtkTreePath *iter_path;
- gboolean finished = FALSE;
-
- iter_path = gtk_tree_model_get_path (model, &child_iter);
- if (end_path && gtk_tree_path_compare (iter_path, end_path) >= 0)
- finished = TRUE;
- gtk_tree_path_free (iter_path);
- if (finished)
- break;
- }
- if (gtk_tree_model_iter_has_child (model, &child_iter))
- count_rows (model, &child_iter, end_path, count, level, depth);
- ret_val = gtk_tree_model_iter_next (model, &child_iter);
- }
- }
-}
-
-/*
- * Find the next node, which has children, at the specified depth below
- * the specified iter. The level is the depth of the current iter.
- * The position of the node is returned in path and the return value of TRUE
- * means that a node was found.
- */
-
-gboolean get_next_node_with_child_at_depth (GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkTreePath **path,
- gint level,
- gint depth)
-{
- GtkTreeIter child_iter;
-
- *path = NULL;
-
- if (gtk_tree_model_iter_children (model, &child_iter, iter))
- {
- level++;
-
- while (TRUE)
- {
- while (!gtk_tree_model_iter_has_child (model, &child_iter))
- {
- if (!gtk_tree_model_iter_next (model, &child_iter))
- return FALSE;
- }
-
- if (level == depth)
- /* We have found what we were looking for */
- {
- *path = gtk_tree_model_get_path (model, &child_iter);
- return TRUE;
- }
-
- if (get_next_node_with_child_at_depth (model, &child_iter, path,
- level, depth))
- return TRUE;
-
- if (!gtk_tree_model_iter_next (model, &child_iter))
- return FALSE;
- }
- }
- return FALSE;
-}
-
-/*
- * Find the next node, which has children, at the same depth as
- * the specified GtkTreePath.
- */
-static gboolean
-get_next_node_with_child (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreePath **return_path)
-{
- GtkTreeIter iter;
- gint depth;
-
- gtk_tree_model_get_iter (model, &iter, path);
-
- while (gtk_tree_model_iter_next (model, &iter))
- {
- if (gtk_tree_model_iter_has_child (model, &iter))
- {
- *return_path = gtk_tree_model_get_path (model, &iter);
- return TRUE;
- }
- }
- depth = gtk_tree_path_get_depth (path);
- while (gtk_tree_path_up (path))
- {
- if (gtk_tree_path_get_depth (path) == 0)
- break;
-
- gtk_tree_model_get_iter (model, &iter, path);
- while (gtk_tree_model_iter_next (model, &iter))
- if (get_next_node_with_child_at_depth (model, &iter, return_path,
- gtk_tree_path_get_depth (path), depth))
- return TRUE;
- }
- *return_path = NULL;
- return FALSE;
-}
-
-static gboolean
-get_tree_path_from_row_index (GtkTreeModel *model,
- gint row_index,
- GtkTreePath **tree_path)
-{
- GtkTreeIter iter;
- gint count;
- gint depth;
-
- count = gtk_tree_model_iter_n_children (model, NULL);
- if (count > row_index)
- {
- if (gtk_tree_model_iter_nth_child (model, &iter, NULL, row_index))
- {
- *tree_path = gtk_tree_model_get_path (model, &iter);
- return TRUE;
- }
- else
- return FALSE;
- }
- else
- row_index -= count;
-
- depth = 0;
- while (TRUE)
- {
- depth++;
-
- if (get_next_node_with_child_at_depth (model, NULL, tree_path, 0, depth))
- {
- GtkTreePath *next_path;
-
- while (TRUE)
- {
- gtk_tree_model_get_iter (model, &iter, *tree_path);
- count = gtk_tree_model_iter_n_children (model, &iter);
- if (count > row_index)
- {
- gtk_tree_path_append_index (*tree_path, row_index);
- return TRUE;
- }
- else
- row_index -= count;
-
- if (!get_next_node_with_child (model, *tree_path, &next_path))
- break;
-
- gtk_tree_path_free (*tree_path);
- *tree_path = next_path;
- }
- }
- else
- {
- g_warning ("Index value is too large\n");
- gtk_tree_path_free (*tree_path);
- *tree_path = NULL;
- return FALSE;
- }
- }
-}
-
-/*
- * This function returns the number of rows, including those which are collapsed
- */
-static gint
-get_row_count (GtkTreeModel *model)
-{
- gint n_rows = 1;
-
- count_rows (model, NULL, NULL, &n_rows, 0, G_MAXINT);
-
- return n_rows;
-}
-
-static gboolean
-get_path_column_from_index (GtkTreeView *tree_view,
- gint index,
- GtkTreePath **path,
- GtkTreeViewColumn **column)
-{
- GtkTreeModel *tree_model;
- gint n_columns;
-
- tree_model = gtk_tree_view_get_model (tree_view);
- n_columns = get_n_actual_columns (tree_view);
- if (n_columns == 0)
- return FALSE;
- /* First row is the column headers */
- index -= n_columns;
- if (index < 0)
- return FALSE;
-
- if (path)
- {
- gint row_index;
- gboolean retval;
-
- row_index = index / n_columns;
- retval = get_tree_path_from_row_index (tree_model, row_index, path);
- gail_return_val_if_fail (retval, FALSE);
- if (*path == NULL)
- return FALSE;
- }
-
- if (column)
- {
- *column = gtk_tree_view_get_column (tree_view, index % n_columns);
- if (*column == NULL)
- {
- if (path)
- gtk_tree_path_free (*path);
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static void
-set_cell_expandable (GailCell *cell)
-{
- if (gail_cell_add_state (cell,
- ATK_STATE_EXPANDABLE,
- FALSE))
- gail_cell_add_action (cell,
- "expand or contract", /* action name */
- "expands or contracts the row in the tree view "
- "containing this cell", /* description */
- NULL, /* Keybinding */
- toggle_cell_expanded);
-}
-
-static GailTreeViewCellInfo*
-find_cell_info (GailTreeView *view,
- GailCell *cell,
- GList** list,
- gboolean live_only)
-{
- GList *temp_list;
- GailTreeViewCellInfo *cell_info;
-
- for (temp_list = view->cell_data; temp_list; temp_list = temp_list->next)
- {
- cell_info = (GailTreeViewCellInfo *) temp_list->data;
- if (cell_info->cell == cell && (!live_only || cell_info->in_use))
- {
- if (list)
- *list = temp_list;
- return cell_info;
- }
- }
- return NULL;
-}
-
-static AtkObject *
-get_header_from_column (GtkTreeViewColumn *tv_col)
-{
- AtkObject *rc;
- GtkWidget *header_widget;
-
- if (tv_col == NULL)
- return NULL;
-
- /* If the user has set a header object, use that */
-
- rc = g_object_get_qdata (G_OBJECT (tv_col), quark_column_header_object);
-
- if (rc == NULL)
- {
- /* If the user has not set a header object, grab the column */
- /* header object defined by the GtkTreeView */
-
- header_widget = gtk_tree_view_column_get_button (tv_col);
-
- if (header_widget)
- {
- rc = gtk_widget_get_accessible (header_widget);
- }
- else
- rc = NULL;
- }
- return rc;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_TREE_VIEW_H__
-#define __GAIL_TREE_VIEW_H__
-
-#include <gtk/gtk.h>
-#include "gailcontainer.h"
-#include "gailcell.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_TREE_VIEW (gail_tree_view_get_type ())
-#define GAIL_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TREE_VIEW, GailTreeView))
-#define GAIL_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TREE_VIEW, GailTreeViewClass))
-#define GAIL_IS_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TREE_VIEW))
-#define GAIL_IS_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TREE_VIEW))
-#define GAIL_TREE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TREE_VIEW, GailTreeViewClass))
-
-typedef struct _GailTreeView GailTreeView;
-typedef struct _GailTreeViewClass GailTreeViewClass;
-
-struct _GailTreeView
-{
- GailContainer parent;
-
- AtkObject* caption;
- AtkObject* summary;
- gint n_children_deleted;
- GArray* col_data;
- GArray* row_data;
- GList* cell_data;
- GtkTreeModel *tree_model;
- AtkObject *focus_cell;
- GtkAdjustment *old_hadj;
- GtkAdjustment *old_vadj;
- guint idle_expand_id;
- guint idle_garbage_collect_id;
- guint idle_cursor_changed_id;
- GtkTreePath *idle_expand_path;
- gboolean garbage_collection_pending;
-};
-
-GType gail_tree_view_get_type (void);
-
-struct _GailTreeViewClass
-{
- GailContainerClass parent_class;
-};
-
-AtkObject* gail_tree_view_ref_focus_cell (GtkTreeView *treeview);
-
-G_END_DECLS
-
-#endif /* __GAIL_TREE_VIEW_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include "gailutil.h"
-#include "gailtoplevel.h"
-#include "gailwindow.h"
-#include "gail-private-macros.h"
-
-static void gail_util_class_init (GailUtilClass *klass);
-static void gail_util_init (GailUtil *utils);
-/* atkutil.h */
-
-static guint gail_util_add_global_event_listener (GSignalEmissionHook listener,
- const gchar* event_type);
-static void gail_util_remove_global_event_listener (guint remove_listener);
-static guint gail_util_add_key_event_listener (AtkKeySnoopFunc listener,
- gpointer data);
-static void gail_util_remove_key_event_listener (guint remove_listener);
-static AtkObject* gail_util_get_root (void);
-static const gchar *gail_util_get_toolkit_name (void);
-static const gchar *gail_util_get_toolkit_version (void);
-
-/* gailmisc/AtkMisc */
-static void gail_misc_class_init (GailMiscClass *klass);
-static void gail_misc_init (GailMisc *misc);
-
-static void gail_misc_threads_enter (AtkMisc *misc);
-static void gail_misc_threads_leave (AtkMisc *misc);
-
-/* Misc */
-
-static void _listener_info_destroy (gpointer data);
-static guint add_listener (GSignalEmissionHook listener,
- const gchar *object_type,
- const gchar *signal,
- const gchar *hook_data);
-static void do_window_event_initialization (void);
-static gboolean state_event_watcher (GSignalInvocationHint *hint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-static void window_added (AtkObject *atk_obj,
- guint index,
- AtkObject *child);
-static void window_removed (AtkObject *atk_obj,
- guint index,
- AtkObject *child);
-static gboolean window_focus (GtkWidget *widget,
- GdkEventFocus *event);
-static gboolean configure_event_watcher (GSignalInvocationHint *hint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-
-
-static AtkObject* root = NULL;
-static GHashTable *listener_list = NULL;
-static gint listener_idx = 1;
-static GSList *key_listener_list = NULL;
-static guint key_snooper_id = 0;
-
-typedef struct _GailUtilListenerInfo GailUtilListenerInfo;
-typedef struct _GailKeyEventInfo GailKeyEventInfo;
-
-struct _GailUtilListenerInfo
-{
- gint key;
- guint signal_id;
- gulong hook_id;
-};
-
-struct _GailKeyEventInfo
-{
- AtkKeyEventStruct *key_event;
- gpointer func_data;
-};
-
-G_DEFINE_TYPE (GailUtil, gail_util, ATK_TYPE_UTIL)
-
-static void
-gail_util_class_init (GailUtilClass *klass)
-{
- AtkUtilClass *atk_class;
- gpointer data;
-
- data = g_type_class_peek (ATK_TYPE_UTIL);
- atk_class = ATK_UTIL_CLASS (data);
-
- atk_class->add_global_event_listener =
- gail_util_add_global_event_listener;
- atk_class->remove_global_event_listener =
- gail_util_remove_global_event_listener;
- atk_class->add_key_event_listener =
- gail_util_add_key_event_listener;
- atk_class->remove_key_event_listener =
- gail_util_remove_key_event_listener;
- atk_class->get_root = gail_util_get_root;
- atk_class->get_toolkit_name = gail_util_get_toolkit_name;
- atk_class->get_toolkit_version = gail_util_get_toolkit_version;
-
- listener_list = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
- _listener_info_destroy);
-}
-
-static void
-gail_util_init (GailUtil *utils)
-{
-}
-
-static guint
-gail_util_add_global_event_listener (GSignalEmissionHook listener,
- const gchar *event_type)
-{
- guint rc = 0;
- gchar **split_string;
-
- split_string = g_strsplit (event_type, ":", 3);
-
- if (split_string)
- {
- if (!strcmp ("window", split_string[0]))
- {
- static gboolean initialized = FALSE;
-
- if (!initialized)
- {
- do_window_event_initialization ();
- initialized = TRUE;
- }
- rc = add_listener (listener, "GailWindow", split_string[1], event_type);
- }
- else
- {
- rc = add_listener (listener, split_string[1], split_string[2], event_type);
- }
-
- g_strfreev (split_string);
- }
-
- return rc;
-}
-
-static void
-gail_util_remove_global_event_listener (guint remove_listener)
-{
- if (remove_listener > 0)
- {
- GailUtilListenerInfo *listener_info;
- gint tmp_idx = remove_listener;
-
- listener_info = (GailUtilListenerInfo *)
- g_hash_table_lookup(listener_list, &tmp_idx);
-
- if (listener_info != NULL)
- {
- /* Hook id of 0 and signal id of 0 are invalid */
- if (listener_info->hook_id != 0 && listener_info->signal_id != 0)
- {
- /* Remove the emission hook */
- g_signal_remove_emission_hook(listener_info->signal_id,
- listener_info->hook_id);
-
- /* Remove the element from the hash */
- g_hash_table_remove(listener_list, &tmp_idx);
- }
- else
- {
- g_warning("Invalid listener hook_id %ld or signal_id %d\n",
- listener_info->hook_id, listener_info->signal_id);
- }
- }
- else
- {
- g_warning("No listener with the specified listener id %d",
- remove_listener);
- }
- }
- else
- {
- g_warning("Invalid listener_id %d", remove_listener);
- }
-}
-
-
-static
-AtkKeyEventStruct *
-atk_key_event_from_gdk_event_key (GdkEventKey *key)
-{
- AtkKeyEventStruct *event = g_new0 (AtkKeyEventStruct, 1);
- switch (key->type)
- {
- case GDK_KEY_PRESS:
- event->type = ATK_KEY_EVENT_PRESS;
- break;
- case GDK_KEY_RELEASE:
- event->type = ATK_KEY_EVENT_RELEASE;
- break;
- default:
- g_assert_not_reached ();
- return NULL;
- }
- event->state = key->state;
- event->keyval = key->keyval;
- event->length = key->length;
- if (key->string && key->string [0] &&
- (key->state & GDK_CONTROL_MASK ||
- g_unichar_isgraph (g_utf8_get_char (key->string))))
- {
- event->string = key->string;
- }
- else if (key->type == GDK_KEY_PRESS ||
- key->type == GDK_KEY_RELEASE)
- {
- event->string = gdk_keyval_name (key->keyval);
- }
- event->keycode = key->hardware_keycode;
- event->timestamp = key->time;
-#ifdef GAIL_DEBUG
- g_print ("GailKey:\tsym %u\n\tmods %x\n\tcode %u\n\ttime %lx\n",
- (unsigned int) event->keyval,
- (unsigned int) event->state,
- (unsigned int) event->keycode,
- (unsigned long int) event->timestamp);
-#endif
- return event;
-}
-
-typedef struct {
- AtkKeySnoopFunc func;
- gpointer data;
- guint key;
-} KeyEventListener;
-
-static gint
-gail_key_snooper (GtkWidget *the_widget, GdkEventKey *event, gpointer data)
-{
- GSList *l;
- AtkKeyEventStruct *atk_event;
- gboolean result;
-
- atk_event = atk_key_event_from_gdk_event_key (event);
-
- result = FALSE;
-
- for (l = key_listener_list; l; l = l->next)
- {
- KeyEventListener *listener = l->data;
-
- result |= listener->func (atk_event, listener->data);
- }
- g_free (atk_event);
-
- return result;
-}
-
-static guint
-gail_util_add_key_event_listener (AtkKeySnoopFunc listener_func,
- gpointer listener_data)
-{
- static guint key = 0;
- KeyEventListener *listener;
-
- if (key_snooper_id == 0)
- key_snooper_id = gtk_key_snooper_install (gail_key_snooper, NULL);
-
- key++;
-
- listener = g_slice_new0 (KeyEventListener);
- listener->func = listener_func;
- listener->data = listener_data;
- listener->key = key;
-
- key_listener_list = g_slist_append (key_listener_list, listener);
-
- return key;
-}
-
-static void
-gail_util_remove_key_event_listener (guint listener_key)
-{
- GSList *l;
-
- for (l = key_listener_list; l; l = l->next)
- {
- KeyEventListener *listener = l->data;
-
- if (listener->key == listener_key)
- {
- g_slice_free (KeyEventListener, listener);
- key_listener_list = g_slist_delete_link (key_listener_list, l);
-
- break;
- }
- }
-
- if (key_listener_list == NULL)
- {
- gtk_key_snooper_remove (key_snooper_id);
- key_snooper_id = 0;
- }
-}
-
-static AtkObject*
-gail_util_get_root (void)
-{
- if (!root)
- {
- root = g_object_new (GAIL_TYPE_TOPLEVEL, NULL);
- atk_object_initialize (root, NULL);
- }
-
- return root;
-}
-
-static const gchar *
-gail_util_get_toolkit_name (void)
-{
- return "GAIL";
-}
-
-static const gchar *
-gail_util_get_toolkit_version (void)
-{
- /*
- * Version is passed in as a -D flag when this file is
- * compiled.
- */
- return GTK_VERSION;
-}
-
-static void
-_listener_info_destroy (gpointer data)
-{
- g_free(data);
-}
-
-static guint
-add_listener (GSignalEmissionHook listener,
- const gchar *object_type,
- const gchar *signal,
- const gchar *hook_data)
-{
- GType type;
- guint signal_id;
- gint rc = 0;
-
- type = g_type_from_name (object_type);
- if (type)
- {
- signal_id = g_signal_lookup (signal, type);
- if (signal_id > 0)
- {
- GailUtilListenerInfo *listener_info;
-
- rc = listener_idx;
-
- listener_info = g_malloc(sizeof(GailUtilListenerInfo));
- listener_info->key = listener_idx;
- listener_info->hook_id =
- g_signal_add_emission_hook (signal_id, 0, listener,
- g_strdup (hook_data),
- (GDestroyNotify) g_free);
- listener_info->signal_id = signal_id;
-
- g_hash_table_insert(listener_list, &(listener_info->key), listener_info);
- listener_idx++;
- }
- else
- {
- g_warning("Invalid signal type %s\n", signal);
- }
- }
- else
- {
- g_warning("Invalid object type %s\n", object_type);
- }
- return rc;
-}
-
-static void
-do_window_event_initialization (void)
-{
- AtkObject *root;
-
- /*
- * Ensure that GailWindowClass exists.
- */
- g_type_class_ref (GAIL_TYPE_WINDOW);
- g_signal_add_emission_hook (g_signal_lookup ("window-state-event", GTK_TYPE_WIDGET),
- 0, state_event_watcher, NULL, (GDestroyNotify) NULL);
- g_signal_add_emission_hook (g_signal_lookup ("configure-event", GTK_TYPE_WIDGET),
- 0, configure_event_watcher, NULL, (GDestroyNotify) NULL);
-
- root = atk_get_root ();
- g_signal_connect (root, "children-changed::add",
- (GCallback) window_added, NULL);
- g_signal_connect (root, "children-changed::remove",
- (GCallback) window_removed, NULL);
-}
-
-static gboolean
-state_event_watcher (GSignalInvocationHint *hint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- GtkWidget *widget;
- AtkObject *atk_obj;
- AtkObject *parent;
- GdkEventWindowState *event;
- gchar *signal_name;
- guint signal_id;
-
- object = g_value_get_object (param_values + 0);
- /*
- * The object can be a GtkMenu when it is popped up; we ignore this
- */
- if (!GTK_IS_WINDOW (object))
- return FALSE;
-
- event = g_value_get_boxed (param_values + 1);
- gail_return_val_if_fail (event->type == GDK_WINDOW_STATE, FALSE);
- widget = GTK_WIDGET (object);
-
- if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
- {
- signal_name = "maximize";
- }
- else if (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)
- {
- signal_name = "minimize";
- }
- else if (event->new_window_state == 0)
- {
- signal_name = "restore";
- }
- else
- return TRUE;
-
- atk_obj = gtk_widget_get_accessible (widget);
-
- if (GAIL_IS_WINDOW (atk_obj))
- {
- parent = atk_object_get_parent (atk_obj);
- if (parent == atk_get_root ())
- {
- signal_id = g_signal_lookup (signal_name, GAIL_TYPE_WINDOW);
- g_signal_emit (atk_obj, signal_id, 0);
- }
-
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-static void
-window_added (AtkObject *atk_obj,
- guint index,
- AtkObject *child)
-{
- GtkWidget *widget;
-
- if (!GAIL_IS_WINDOW (child)) return;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (child));
- gail_return_if_fail (widget);
-
- g_signal_connect (widget, "focus-in-event",
- (GCallback) window_focus, NULL);
- g_signal_connect (widget, "focus-out-event",
- (GCallback) window_focus, NULL);
- g_signal_emit (child, g_signal_lookup ("create", GAIL_TYPE_WINDOW), 0);
-}
-
-
-static void
-window_removed (AtkObject *atk_obj,
- guint index,
- AtkObject *child)
-{
- GtkWidget *widget;
- GtkWindow *window;
-
- if (!GAIL_IS_WINDOW (child)) return;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (child));
- gail_return_if_fail (widget);
-
- window = GTK_WINDOW (widget);
- /*
- * Deactivate window if it is still focused and we are removing it. This
- * can happen when a dialog displayed by gok is removed.
- */
- if (gtk_window_is_active (window) &&
- gtk_window_has_toplevel_focus (window))
- {
- gchar *signal_name;
- AtkObject *atk_obj;
-
- atk_obj = gtk_widget_get_accessible (widget);
- signal_name = "deactivate";
- g_signal_emit (atk_obj, g_signal_lookup (signal_name, GAIL_TYPE_WINDOW), 0);
- }
-
- g_signal_handlers_disconnect_by_func (widget, (gpointer) window_focus, NULL);
- g_signal_emit (child, g_signal_lookup ("destroy", GAIL_TYPE_WINDOW), 0);
-}
-
-static gboolean
-window_focus (GtkWidget *widget,
- GdkEventFocus *event)
-{
- gchar *signal_name;
- AtkObject *atk_obj;
-
- g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
-
- atk_obj = gtk_widget_get_accessible (widget);
- signal_name = (event->in) ? "activate" : "deactivate";
- g_signal_emit (atk_obj, g_signal_lookup (signal_name, GAIL_TYPE_WINDOW), 0);
-
- return FALSE;
-}
-
-static gboolean
-configure_event_watcher (GSignalInvocationHint *hint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GtkAllocation allocation;
- GObject *object;
- GtkWidget *widget;
- AtkObject *atk_obj;
- AtkObject *parent;
- GdkEvent *event;
- gchar *signal_name;
- guint signal_id;
-
- object = g_value_get_object (param_values + 0);
- if (!GTK_IS_WINDOW (object))
- /*
- * GtkDrawingArea can send a GDK_CONFIGURE event but we ignore here
- */
- return FALSE;
-
- event = g_value_get_boxed (param_values + 1);
- if (event->type != GDK_CONFIGURE)
- return FALSE;
- widget = GTK_WIDGET (object);
- gtk_widget_get_allocation (widget, &allocation);
- if (allocation.x == ((GdkEventConfigure *)event)->x &&
- allocation.y == ((GdkEventConfigure *)event)->y &&
- allocation.width == ((GdkEventConfigure *)event)->width &&
- allocation.height == ((GdkEventConfigure *)event)->height)
- return TRUE;
-
- if (allocation.width != ((GdkEventConfigure *)event)->width ||
- allocation.height != ((GdkEventConfigure *)event)->height)
- {
- signal_name = "resize";
- }
- else
- {
- signal_name = "move";
- }
-
- atk_obj = gtk_widget_get_accessible (widget);
- if (GAIL_IS_WINDOW (atk_obj))
- {
- parent = atk_object_get_parent (atk_obj);
- if (parent == atk_get_root ())
- {
- signal_id = g_signal_lookup (signal_name, GAIL_TYPE_WINDOW);
- g_signal_emit (atk_obj, signal_id, 0);
- }
-
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-G_DEFINE_TYPE (GailMisc, gail_misc, ATK_TYPE_MISC)
-
-static void
-gail_misc_class_init (GailMiscClass *klass)
-{
- AtkMiscClass *miscclass = ATK_MISC_CLASS (klass);
- miscclass->threads_enter =
- gail_misc_threads_enter;
- miscclass->threads_leave =
- gail_misc_threads_leave;
- atk_misc_instance = g_object_new (GAIL_TYPE_MISC, NULL);
-}
-
-static void
-gail_misc_init (GailMisc *misc)
-{
-}
-
-static void gail_misc_threads_enter (AtkMisc *misc)
-{
- GDK_THREADS_ENTER ();
-}
-
-static void gail_misc_threads_leave (AtkMisc *misc)
-{
- GDK_THREADS_LEAVE ();
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_UTIL_H__
-#define __GAIL_UTIL_H__
-
-#include <atk/atk.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_UTIL (gail_util_get_type ())
-#define GAIL_UTIL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_UTIL, GailUtil))
-#define GAIL_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_UTIL, GailUtilClass))
-#define GAIL_IS_UTIL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_UTIL))
-#define GAIL_IS_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_UTIL))
-#define GAIL_UTIL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_UTIL, GailUtilClass))
-
-typedef struct _GailUtil GailUtil;
-typedef struct _GailUtilClass GailUtilClass;
-
-struct _GailUtil
-{
- AtkUtil parent;
- GList *listener_list;
-};
-
-GType gail_util_get_type (void);
-
-struct _GailUtilClass
-{
- AtkUtilClass parent_class;
-};
-
-#define GAIL_TYPE_MISC (gail_misc_get_type ())
-#define GAIL_MISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_MISC, GailMisc))
-#define GAIL_MISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_MISC, GailMiscClass))
-#define GAIL_IS_MISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_MISC))
-#define GAIL_IS_MISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_MISC))
-#define GAIL_MISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_MISC, GailMiscClass))
-
-typedef struct _GailMisc GailMisc;
-typedef struct _GailMiscClass GailMiscClass;
-
-struct _GailMisc
-{
- AtkMisc parent;
-};
-
-GType gail_misc_get_type (void);
-
-struct _GailMiscClass
-{
- AtkMiscClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_UTIL_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-
-#include <gtk/gtk.h>
-#ifdef GDK_WINDOWING_X11
-#include <gdk/x11/gdkx.h>
-#endif
-#include "gailwidget.h"
-#include "gailnotebookpage.h"
-#include "gail-private-macros.h"
-
-extern GtkWidget *focus_widget;
-
-static void gail_widget_class_init (GailWidgetClass *klass);
-static void gail_widget_init (GailWidget *accessible);
-static void gail_widget_connect_widget_destroyed (GtkAccessible *accessible);
-static void gail_widget_destroyed (GtkWidget *widget,
- GtkAccessible *accessible);
-
-static const gchar* gail_widget_get_description (AtkObject *accessible);
-static AtkObject* gail_widget_get_parent (AtkObject *accessible);
-static AtkStateSet* gail_widget_ref_state_set (AtkObject *accessible);
-static AtkRelationSet* gail_widget_ref_relation_set (AtkObject *accessible);
-static gint gail_widget_get_index_in_parent (AtkObject *accessible);
-
-static void atk_component_interface_init (AtkComponentIface *iface);
-
-static guint gail_widget_add_focus_handler
- (AtkComponent *component,
- AtkFocusHandler handler);
-
-static void gail_widget_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type);
-
-static void gail_widget_get_size (AtkComponent *component,
- gint *width,
- gint *height);
-
-static AtkLayer gail_widget_get_layer (AtkComponent *component);
-
-static gboolean gail_widget_grab_focus (AtkComponent *component);
-
-
-static void gail_widget_remove_focus_handler
- (AtkComponent *component,
- guint handler_id);
-
-static gboolean gail_widget_set_extents (AtkComponent *component,
- gint x,
- gint y,
- gint width,
- gint height,
- AtkCoordType coord_type);
-
-static gboolean gail_widget_set_position (AtkComponent *component,
- gint x,
- gint y,
- AtkCoordType coord_type);
-
-static gboolean gail_widget_set_size (AtkComponent *component,
- gint width,
- gint height);
-
-static gint gail_widget_map_gtk (GtkWidget *widget);
-static void gail_widget_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-static void gail_widget_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-static gboolean gail_widget_focus_gtk (GtkWidget *widget,
- GdkEventFocus *event);
-static gboolean gail_widget_real_focus_gtk (GtkWidget *widget,
- GdkEventFocus *event);
-static void gail_widget_size_allocate_gtk (GtkWidget *widget,
- GtkAllocation *allocation);
-
-static void gail_widget_focus_event (AtkObject *obj,
- gboolean focus_in);
-
-static void gail_widget_real_initialize (AtkObject *obj,
- gpointer data);
-static AtkAttributeSet *gail_widget_get_attributes(AtkObject *obj);
-static GtkWidget* gail_widget_find_viewport (GtkWidget *widget);
-static gboolean gail_widget_on_screen (GtkWidget *widget);
-static gboolean gail_widget_all_parents_visible(GtkWidget *widget);
-
-G_DEFINE_TYPE_WITH_CODE (GailWidget, gail_widget, GTK_TYPE_ACCESSIBLE,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
-
-static void
-gail_widget_class_init (GailWidgetClass *klass)
-{
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
- GtkAccessibleClass *accessible_class = GTK_ACCESSIBLE_CLASS (klass);
-
- klass->notify_gtk = gail_widget_real_notify_gtk;
- klass->focus_gtk = gail_widget_real_focus_gtk;
-
- accessible_class->connect_widget_destroyed = gail_widget_connect_widget_destroyed;
-
- class->get_description = gail_widget_get_description;
- class->get_parent = gail_widget_get_parent;
- class->ref_relation_set = gail_widget_ref_relation_set;
- class->ref_state_set = gail_widget_ref_state_set;
- class->get_index_in_parent = gail_widget_get_index_in_parent;
- class->initialize = gail_widget_real_initialize;
- class->get_attributes = gail_widget_get_attributes;
-}
-
-static void
-gail_widget_init (GailWidget *accessible)
-{
-}
-
-/**
- * This function specifies the GtkWidget for which the GailWidget was created
- * and specifies a handler to be called when the GtkWidget is destroyed.
- **/
-static void
-gail_widget_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkAccessible *accessible;
- GtkWidget *widget;
-
- g_return_if_fail (GTK_IS_WIDGET (data));
-
- widget = GTK_WIDGET (data);
-
- accessible = GTK_ACCESSIBLE (obj);
- gtk_accessible_set_widget (accessible, widget);
- gtk_accessible_connect_widget_destroyed (accessible);
- g_signal_connect_after (widget,
- "focus-in-event",
- G_CALLBACK (gail_widget_focus_gtk),
- NULL);
- g_signal_connect_after (widget,
- "focus-out-event",
- G_CALLBACK (gail_widget_focus_gtk),
- NULL);
- g_signal_connect (widget,
- "notify",
- G_CALLBACK (gail_widget_notify_gtk),
- NULL);
- g_signal_connect (widget,
- "size_allocate",
- G_CALLBACK (gail_widget_size_allocate_gtk),
- NULL);
- atk_component_add_focus_handler (ATK_COMPONENT (accessible),
- gail_widget_focus_event);
- /*
- * Add signal handlers for GTK signals required to support property changes
- */
- g_signal_connect (widget,
- "map",
- G_CALLBACK (gail_widget_map_gtk),
- NULL);
- g_signal_connect (widget,
- "unmap",
- G_CALLBACK (gail_widget_map_gtk),
- NULL);
- g_object_set_data (G_OBJECT (obj), "atk-component-layer",
- GINT_TO_POINTER (ATK_LAYER_WIDGET));
-
- obj->role = ATK_ROLE_UNKNOWN;
-}
-
-AtkObject*
-gail_widget_new (GtkWidget *widget)
-{
- GObject *object;
- AtkObject *accessible;
-
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- object = g_object_new (GAIL_TYPE_WIDGET, NULL);
-
- accessible = ATK_OBJECT (object);
- atk_object_initialize (accessible, widget);
-
- return accessible;
-}
-
-/*
- * This function specifies the function to be called when the widget
- * is destroyed
- */
-static void
-gail_widget_connect_widget_destroyed (GtkAccessible *accessible)
-{
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- if (widget)
- {
- g_signal_connect_after (widget,
- "destroy",
- G_CALLBACK (gail_widget_destroyed),
- accessible);
- }
-}
-
-/*
- * This function is called when the widget is destroyed.
- * It sets the widget field in the GtkAccessible structure to NULL
- * and emits a state-change signal for the state ATK_STATE_DEFUNCT
- */
-static void
-gail_widget_destroyed (GtkWidget *widget,
- GtkAccessible *accessible)
-{
- gtk_accessible_set_widget (accessible, NULL);
- atk_object_notify_state_change (ATK_OBJECT (accessible), ATK_STATE_DEFUNCT,
- TRUE);
-}
-
-static const gchar*
-gail_widget_get_description (AtkObject *accessible)
-{
- if (accessible->description)
- return accessible->description;
- else
- {
- GtkWidget *widget;
-
- /* Get the tooltip from the widget */
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- if (widget == NULL)
- /*
- * Object is defunct
- */
- return NULL;
-
- return gtk_widget_get_tooltip_text (widget);
- }
-}
-
-static AtkObject*
-gail_widget_get_parent (AtkObject *accessible)
-{
- AtkObject *parent;
-
- parent = accessible->accessible_parent;
-
- if (parent != NULL)
- g_return_val_if_fail (ATK_IS_OBJECT (parent), NULL);
- else
- {
- GtkWidget *widget, *parent_widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
- gail_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- parent_widget = gtk_widget_get_parent (widget);
- if (parent_widget == NULL)
- return NULL;
-
- /*
- * For a widget whose parent is a GtkNoteBook, we return the
- * accessible object corresponding the GtkNotebookPage containing
- * the widget as the accessible parent.
- */
- if (GTK_IS_NOTEBOOK (parent_widget))
- {
- gint page_num;
- GtkWidget *child;
- GtkNotebook *notebook;
-
- page_num = 0;
- notebook = GTK_NOTEBOOK (parent_widget);
- while (TRUE)
- {
- child = gtk_notebook_get_nth_page (notebook, page_num);
- if (!child)
- break;
- if (child == widget)
- {
- parent = gtk_widget_get_accessible (parent_widget);
- parent = atk_object_ref_accessible_child (parent, page_num);
- g_object_unref (parent);
- return parent;
- }
- page_num++;
- }
- }
-
- parent = gtk_widget_get_accessible (parent_widget);
- }
- return parent;
-}
-
-static GtkWidget*
-find_label (GtkWidget *widget)
-{
- GList *labels;
- GtkWidget *label;
- GtkWidget *temp_widget;
-
- labels = gtk_widget_list_mnemonic_labels (widget);
- label = NULL;
- if (labels)
- {
- if (labels->data)
- {
- if (labels->next)
- {
- g_warning ("Widget (%s) has more than one label", G_OBJECT_TYPE_NAME (widget));
-
- }
- else
- {
- label = labels->data;
- }
- }
- g_list_free (labels);
- }
-
- /*
- * Ignore a label within a button; bug #136602
- */
- if (label && GTK_IS_BUTTON (widget))
- {
- temp_widget = label;
- while (temp_widget)
- {
- if (temp_widget == widget)
- {
- label = NULL;
- break;
- }
- temp_widget = gtk_widget_get_parent (temp_widget);
- }
- }
- return label;
-}
-
-static AtkRelationSet*
-gail_widget_ref_relation_set (AtkObject *obj)
-{
- GtkWidget *widget;
- AtkRelationSet *relation_set;
- GtkWidget *label;
- AtkObject *array[1];
- AtkRelation* relation;
-
- gail_return_val_if_fail (GAIL_IS_WIDGET (obj), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- relation_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_relation_set (obj);
-
- if (GTK_IS_BOX (widget))
- /*
- * Do not report labelled-by for a GtkBox which could be a
- * GnomeFileEntry.
- */
- return relation_set;
-
- if (!atk_relation_set_contains (relation_set, ATK_RELATION_LABELLED_BY))
- {
- label = find_label (widget);
- if (label == NULL)
- {
- if (GTK_IS_BUTTON (widget))
- /*
- * Handle the case where GnomeIconEntry is the mnemonic widget.
- * The GtkButton which is a grandchild of the GnomeIconEntry
- * should really be the mnemonic widget. See bug #133967.
- */
- {
- GtkWidget *temp_widget;
-
- temp_widget = gtk_widget_get_parent (widget);
-
- if (GTK_IS_ALIGNMENT (temp_widget))
- {
- temp_widget = gtk_widget_get_parent (temp_widget);
- if (GTK_IS_BOX (temp_widget))
- {
- label = find_label (temp_widget);
-
- if (!label)
- label = find_label (gtk_widget_get_parent (temp_widget));
- }
- }
- }
- else if (GTK_IS_COMBO_BOX (widget))
- /*
- * Handle the case when GtkFileChooserButton is the mnemonic
- * widget. The GtkComboBox which is a child of the
- * GtkFileChooserButton should be the mnemonic widget.
- * See bug #359843.
- */
- {
- GtkWidget *temp_widget;
-
- temp_widget = gtk_widget_get_parent (widget);
- if (GTK_IS_BOX (temp_widget))
- {
- label = find_label (temp_widget);
- }
- }
- }
-
- if (label)
- {
- array [0] = gtk_widget_get_accessible (label);
-
- relation = atk_relation_new (array, 1, ATK_RELATION_LABELLED_BY);
- atk_relation_set_add (relation_set, relation);
- g_object_unref (relation);
- }
- }
-
- return relation_set;
-}
-
-static AtkStateSet*
-gail_widget_ref_state_set (AtkObject *accessible)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- AtkStateSet *state_set;
-
- state_set = ATK_OBJECT_CLASS (gail_widget_parent_class)->ref_state_set (accessible);
-
- if (widget == NULL)
- {
- atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT);
- }
- else
- {
- if (gtk_widget_is_sensitive (widget))
- {
- atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
- atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
- }
-
- if (gtk_widget_get_can_focus (widget))
- {
- atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE);
- }
- /*
- * We do not currently generate notifications when an ATK object
- * corresponding to a GtkWidget changes visibility by being scrolled
- * on or off the screen. The testcase for this is the main window
- * of the testgtk application in which a set of buttons in a GtkVBox
- * is in a scrooled window with a viewport.
- *
- * To generate the notifications we would need to do the following:
- * 1) Find the GtkViewPort among the antecendents of the objects
- * 2) Create an accesible for the GtkViewPort
- * 3) Connect to the value-changed signal on the viewport
- * 4) When the signal is received we need to traverse the children
- * of the viewport and check whether the children are visible or not
- * visible; we may want to restrict this to the widgets for which
- * accessible objects have been created.
- * 5) We probably need to store a variable on_screen in the
- * GailWidget data structure so we can determine whether the value has
- * changed.
- */
- if (gtk_widget_get_visible (widget))
- {
- atk_state_set_add_state (state_set, ATK_STATE_VISIBLE);
- if (gail_widget_on_screen (widget) && gtk_widget_get_mapped (widget) &&
- gail_widget_all_parents_visible (widget))
- {
- atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
- }
- }
-
- if (gtk_widget_has_focus (widget) && (widget == focus_widget))
- {
- AtkObject *focus_obj;
-
- focus_obj = g_object_get_data (G_OBJECT (accessible), "gail-focus-object");
- if (focus_obj == NULL)
- atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
- }
- if (gtk_widget_has_default (widget))
- {
- atk_state_set_add_state (state_set, ATK_STATE_DEFAULT);
- }
-
- if (GTK_IS_ORIENTABLE(widget))
- switch (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)))
- {
- case GTK_ORIENTATION_HORIZONTAL:
- atk_state_set_add_state (state_set, ATK_STATE_HORIZONTAL);
- break;
-
- case GTK_ORIENTATION_VERTICAL:
- atk_state_set_add_state (state_set, ATK_STATE_VERTICAL);
- break;
- }
- }
- return state_set;
-}
-
-static gint
-gail_widget_get_index_in_parent (AtkObject *accessible)
-{
- GtkWidget *widget;
- GtkWidget *parent_widget;
- gint index;
- GList *children;
- GType type;
-
- type = g_type_from_name ("GailCanvasWidget");
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return -1;
-
- if (accessible->accessible_parent)
- {
- AtkObject *parent;
-
- parent = accessible->accessible_parent;
-
- if (GAIL_IS_NOTEBOOK_PAGE (parent) ||
- G_TYPE_CHECK_INSTANCE_TYPE ((parent), type))
- return 0;
- else
- {
- gint n_children, i;
- gboolean found = FALSE;
-
- n_children = atk_object_get_n_accessible_children (parent);
- for (i = 0; i < n_children; i++)
- {
- AtkObject *child;
-
- child = atk_object_ref_accessible_child (parent, i);
- if (child == accessible)
- found = TRUE;
-
- g_object_unref (child);
- if (found)
- return i;
- }
- }
- }
-
- gail_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
- parent_widget = gtk_widget_get_parent (widget);
- if (parent_widget == NULL)
- return -1;
- gail_return_val_if_fail (GTK_IS_CONTAINER (parent_widget), -1);
-
- children = gtk_container_get_children (GTK_CONTAINER (parent_widget));
-
- index = g_list_index (children, widget);
- g_list_free (children);
- return index;
-}
-
-static void
-atk_component_interface_init (AtkComponentIface *iface)
-{
- /*
- * Use default implementation for contains and get_position
- */
- iface->add_focus_handler = gail_widget_add_focus_handler;
- iface->get_extents = gail_widget_get_extents;
- iface->get_size = gail_widget_get_size;
- iface->get_layer = gail_widget_get_layer;
- iface->grab_focus = gail_widget_grab_focus;
- iface->remove_focus_handler = gail_widget_remove_focus_handler;
- iface->set_extents = gail_widget_set_extents;
- iface->set_position = gail_widget_set_position;
- iface->set_size = gail_widget_set_size;
-}
-
-static guint
-gail_widget_add_focus_handler (AtkComponent *component,
- AtkFocusHandler handler)
-{
- GSignalMatchType match_type;
- gulong ret;
- guint signal_id;
-
- match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC;
- signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT);
-
- ret = g_signal_handler_find (component, match_type, signal_id, 0, NULL,
- (gpointer) handler, NULL);
- if (!ret)
- {
- return g_signal_connect_closure_by_id (component,
- signal_id, 0,
- g_cclosure_new (
- G_CALLBACK (handler), NULL,
- (GClosureNotify) NULL),
- FALSE);
- }
- else
- {
- return 0;
- }
-}
-
-static void
-gail_widget_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type)
-{
- GtkAllocation allocation;
- GdkWindow *window;
- gint x_window, y_window;
- gint x_toplevel, y_toplevel;
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
-
- if (widget == NULL)
- /*
- * Object is defunct
- */
- return;
-
- gail_return_if_fail (GTK_IS_WIDGET (widget));
-
- gtk_widget_get_allocation (widget, &allocation);
- *width = allocation.width;
- *height = allocation.height;
- if (!gail_widget_on_screen (widget) || (!gtk_widget_is_drawable (widget)))
- {
- *x = G_MININT;
- *y = G_MININT;
- return;
- }
-
- if (gtk_widget_get_parent (widget))
- {
- *x = allocation.x;
- *y = allocation.y;
- window = gtk_widget_get_parent_window (widget);
- }
- else
- {
- *x = 0;
- *y = 0;
- window = gtk_widget_get_window (widget);
- }
- gdk_window_get_origin (window, &x_window, &y_window);
- *x += x_window;
- *y += y_window;
-
-
- if (coord_type == ATK_XY_WINDOW)
- {
- window = gdk_window_get_toplevel (gtk_widget_get_window (widget));
- gdk_window_get_origin (window, &x_toplevel, &y_toplevel);
-
- *x -= x_toplevel;
- *y -= y_toplevel;
- }
-}
-
-static void
-gail_widget_get_size (AtkComponent *component,
- gint *width,
- gint *height)
-{
- GtkAllocation allocation;
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
-
- if (widget == NULL)
- /*
- * Object is defunct
- */
- return;
-
- gail_return_if_fail (GTK_IS_WIDGET (widget));
-
- gtk_widget_get_allocation (widget, &allocation);
- *width = allocation.width;
- *height = allocation.height;
-}
-
-static AtkLayer
-gail_widget_get_layer (AtkComponent *component)
-{
- gint layer;
- layer = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (component), "atk-component-layer"));
-
- return (AtkLayer) layer;
-}
-
-static gboolean
-gail_widget_grab_focus (AtkComponent *component)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
- GtkWidget *toplevel;
-
- gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
- if (gtk_widget_get_can_focus (widget))
- {
- gtk_widget_grab_focus (widget);
- toplevel = gtk_widget_get_toplevel (widget);
- if (gtk_widget_is_toplevel (toplevel))
- {
-#ifdef GDK_WINDOWING_X11
- gtk_window_present_with_time (GTK_WINDOW (toplevel),
- gdk_x11_get_server_time (gtk_widget_get_window (widget)));
-#else
- gtk_window_present (GTK_WINDOW (toplevel));
-#endif
- }
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static void
-gail_widget_remove_focus_handler (AtkComponent *component,
- guint handler_id)
-{
- g_signal_handler_disconnect (component, handler_id);
-}
-
-static gboolean
-gail_widget_set_extents (AtkComponent *component,
- gint x,
- gint y,
- gint width,
- gint height,
- AtkCoordType coord_type)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
-
- if (widget == NULL)
- /*
- * Object is defunct
- */
- return FALSE;
- gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
-
- if (gtk_widget_is_toplevel (widget))
- {
- if (coord_type == ATK_XY_WINDOW)
- {
- gint x_current, y_current;
- GdkWindow *window = gtk_widget_get_window (widget);
-
- gdk_window_get_origin (window, &x_current, &y_current);
- x_current += x;
- y_current += y;
- if (x_current < 0 || y_current < 0)
- return FALSE;
- else
- {
- gtk_window_move (GTK_WINDOW (widget), x_current, y_current);
- gtk_widget_set_size_request (widget, width, height);
- return TRUE;
- }
- }
- else if (coord_type == ATK_XY_SCREEN)
- {
- gtk_window_move (GTK_WINDOW (widget), x, y);
- gtk_widget_set_size_request (widget, width, height);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static gboolean
-gail_widget_set_position (AtkComponent *component,
- gint x,
- gint y,
- AtkCoordType coord_type)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
-
- if (widget == NULL)
- /*
- * Object is defunct
- */
- return FALSE;
- gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
-
- if (gtk_widget_is_toplevel (widget))
- {
- if (coord_type == ATK_XY_WINDOW)
- {
- gint x_current, y_current;
- GdkWindow *window = gtk_widget_get_window (widget);
-
- gdk_window_get_origin (window, &x_current, &y_current);
- x_current += x;
- y_current += y;
- if (x_current < 0 || y_current < 0)
- return FALSE;
- else
- {
- gtk_window_move (GTK_WINDOW (widget), x_current, y_current);
- return TRUE;
- }
- }
- else if (coord_type == ATK_XY_SCREEN)
- {
- gtk_window_move (GTK_WINDOW (widget), x, y);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static gboolean
-gail_widget_set_size (AtkComponent *component,
- gint width,
- gint height)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
-
- if (widget == NULL)
- /*
- * Object is defunct
- */
- return FALSE;
- gail_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
-
- if (gtk_widget_is_toplevel (widget))
- {
- gtk_widget_set_size_request (widget, width, height);
- return TRUE;
- }
- else
- return FALSE;
-}
-
-/*
- * This function is a signal handler for notify_in_event and focus_out_event
- * signal which gets emitted on a GtkWidget.
- */
-static gboolean
-gail_widget_focus_gtk (GtkWidget *widget,
- GdkEventFocus *event)
-{
- GailWidget *gail_widget;
- GailWidgetClass *klass;
-
- gail_widget = GAIL_WIDGET (gtk_widget_get_accessible (widget));
- klass = GAIL_WIDGET_GET_CLASS (gail_widget);
- if (klass->focus_gtk)
- return klass->focus_gtk (widget, event);
- else
- return FALSE;
-}
-
-/*
- * This function is the signal handler defined for focus_in_event and
- * focus_out_event got GailWidget.
- *
- * It emits a focus-event signal on the GailWidget.
- */
-static gboolean
-gail_widget_real_focus_gtk (GtkWidget *widget,
- GdkEventFocus *event)
-{
- AtkObject* accessible;
- gboolean return_val;
- return_val = FALSE;
-
- accessible = gtk_widget_get_accessible (widget);
- g_signal_emit_by_name (accessible, "focus_event", event->in, &return_val);
- return FALSE;
-}
-
-static void
-gail_widget_size_allocate_gtk (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- AtkObject* accessible;
- AtkRectangle rect;
-
- accessible = gtk_widget_get_accessible (widget);
- if (ATK_IS_COMPONENT (accessible))
- {
- rect.x = allocation->x;
- rect.y = allocation->y;
- rect.width = allocation->width;
- rect.height = allocation->height;
- g_signal_emit_by_name (accessible, "bounds_changed", &rect);
- }
-}
-
-/*
- * This function is the signal handler defined for map and unmap signals.
- */
-static gint
-gail_widget_map_gtk (GtkWidget *widget)
-{
- AtkObject* accessible;
-
- accessible = gtk_widget_get_accessible (widget);
- atk_object_notify_state_change (accessible, ATK_STATE_SHOWING,
- gtk_widget_get_mapped (widget));
- return 1;
-}
-
-/*
- * This function is a signal handler for notify signal which gets emitted
- * when a property changes value on the GtkWidget associated with the object.
- *
- * It calls a function for the GailWidget type
- */
-static void
-gail_widget_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GailWidget *widget;
- GailWidgetClass *klass;
-
- widget = GAIL_WIDGET (gtk_widget_get_accessible (GTK_WIDGET (obj)));
- klass = GAIL_WIDGET_GET_CLASS (widget);
- if (klass->notify_gtk)
- klass->notify_gtk (obj, pspec);
-}
-
-/*
- * This function is a signal handler for notify signal which gets emitted
- * when a property changes value on the GtkWidget associated with a GailWidget.
- *
- * It constructs an AtkPropertyValues structure and emits a "property_changed"
- * signal which causes the user specified AtkPropertyChangeHandler
- * to be called.
- */
-static void
-gail_widget_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkWidget* widget = GTK_WIDGET (obj);
- AtkObject* atk_obj = gtk_widget_get_accessible (widget);
- AtkState state;
- gboolean value;
-
- if (strcmp (pspec->name, "has-focus") == 0)
- /*
- * We use focus-in-event and focus-out-event signals to catch
- * focus changes so we ignore this.
- */
- return;
- else if (strcmp (pspec->name, "visible") == 0)
- {
- state = ATK_STATE_VISIBLE;
- value = gtk_widget_get_visible (widget);
- }
- else if (strcmp (pspec->name, "sensitive") == 0)
- {
- state = ATK_STATE_SENSITIVE;
- value = gtk_widget_get_sensitive (widget);
- }
- else if (strcmp (pspec->name, "orientation") == 0)
- {
- GtkOrientable *orientable;
-
- orientable = GTK_ORIENTABLE (widget);
-
- state = ATK_STATE_HORIZONTAL;
- value = (gtk_orientable_get_orientation (orientable) == GTK_ORIENTATION_HORIZONTAL);
- }
- else
- return;
-
- atk_object_notify_state_change (atk_obj, state, value);
- if (state == ATK_STATE_SENSITIVE)
- atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, value);
-
- if (state == ATK_STATE_HORIZONTAL)
- atk_object_notify_state_change (atk_obj, ATK_STATE_VERTICAL, !value);
-}
-
-static void
-gail_widget_focus_event (AtkObject *obj,
- gboolean focus_in)
-{
- AtkObject *focus_obj;
-
- focus_obj = g_object_get_data (G_OBJECT (obj), "gail-focus-object");
- if (focus_obj == NULL)
- focus_obj = obj;
- atk_object_notify_state_change (focus_obj, ATK_STATE_FOCUSED, focus_in);
-}
-
-static GtkWidget*
-gail_widget_find_viewport (GtkWidget *widget)
-{
- /*
- * Find an antecedent which is a GtkViewPort
- */
- GtkWidget *parent;
-
- parent = gtk_widget_get_parent (widget);
- while (parent != NULL)
- {
- if (GTK_IS_VIEWPORT (parent))
- break;
- parent = gtk_widget_get_parent (parent);
- }
- return parent;
-}
-
-/*
- * This function checks whether the widget has an antecedent which is
- * a GtkViewport and, if so, whether any part of the widget intersects
- * the visible rectangle of the GtkViewport.
- */
-static gboolean gail_widget_on_screen (GtkWidget *widget)
-{
- GtkAllocation allocation;
- GtkWidget *viewport;
- gboolean return_value;
-
- gtk_widget_get_allocation (widget, &allocation);
-
- viewport = gail_widget_find_viewport (widget);
- if (viewport)
- {
- GtkAllocation viewport_allocation;
- GtkAdjustment *adjustment;
- GdkRectangle visible_rect;
-
- gtk_widget_get_allocation (viewport, &viewport_allocation);
-
- adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (viewport));
- visible_rect.y = gtk_adjustment_get_value (adjustment);
- adjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (viewport));
- visible_rect.x = gtk_adjustment_get_value (adjustment);
- visible_rect.width = viewport_allocation.width;
- visible_rect.height = viewport_allocation.height;
-
- if (((allocation.x + allocation.width) < visible_rect.x) ||
- ((allocation.y + allocation.height) < visible_rect.y) ||
- (allocation.x > (visible_rect.x + visible_rect.width)) ||
- (allocation.y > (visible_rect.y + visible_rect.height)))
- return_value = FALSE;
- else
- return_value = TRUE;
- }
- else
- {
- /*
- * Check whether the widget has been placed of the screen. The
- * widget may be MAPPED as when toolbar items do not fit on the toolbar.
- */
- if (allocation.x + allocation.width <= 0 &&
- allocation.y + allocation.height <= 0)
- return_value = FALSE;
- else
- return_value = TRUE;
- }
-
- return return_value;
-}
-
-/**
- * gail_widget_all_parents_visible:
- * @widget: a #GtkWidget
- *
- * Checks if all the predecesors (the parent widget, his parent, etc) are visible
- * Used to check properly the SHOWING state.
- *
- * Return value: TRUE if all the parent hierarchy is visible, FALSE otherwise
- **/
-static gboolean gail_widget_all_parents_visible (GtkWidget *widget)
-{
- GtkWidget *iter_parent = NULL;
- gboolean result = TRUE;
-
- for (iter_parent = gtk_widget_get_parent (widget); iter_parent;
- iter_parent = gtk_widget_get_parent (iter_parent))
- {
- if (!gtk_widget_get_visible (iter_parent))
- {
- result = FALSE;
- break;
- }
- }
-
- return result;
-}
-
-static AtkAttributeSet *gail_widget_get_attributes(AtkObject *obj)
-{
- AtkAttributeSet *attributes;
- AtkAttribute *toolkit = g_malloc(sizeof(AtkAttribute));
-
- toolkit->name = g_strdup("toolkit");
- toolkit->value = g_strdup("gail");
-
- attributes = g_slist_append(NULL, toolkit);
-
- return attributes;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_WIDGET_H__
-#define __GAIL_WIDGET_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_WIDGET (gail_widget_get_type ())
-#define GAIL_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_WIDGET, GailWidget))
-#define GAIL_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_WIDGET, GailWidgetClass))
-#define GAIL_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_WIDGET))
-#define GAIL_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_WIDGET))
-#define GAIL_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_WIDGET, GailWidgetClass))
-
-typedef struct _GailWidget GailWidget;
-typedef struct _GailWidgetClass GailWidgetClass;
-
-struct _GailWidget
-{
- GtkAccessible parent;
-};
-
-GType gail_widget_get_type (void);
-
-struct _GailWidgetClass
-{
- GtkAccessibleClass parent_class;
-
- /*
- * Signal handler for notify signal on GTK widget
- */
- void (*notify_gtk) (GObject *object,
- GParamSpec *pspec);
- /*
- * Signal handler for focus_in_event and focus_out_event signal on GTK widget
- */
- gboolean (*focus_gtk) (GtkWidget *widget,
- GdkEventFocus *event);
-
-};
-
-AtkObject* gail_widget_new (GtkWidget *widget);
-
-G_END_DECLS
-
-#endif /* __GAIL_WIDGET_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-
-#include <gtk/gtkx.h>
-
-#include "gailwindow.h"
-#include "gailtoplevel.h"
-#include "gail-private-macros.h"
-
-enum {
- ACTIVATE,
- CREATE,
- DEACTIVATE,
- DESTROY,
- MAXIMIZE,
- MINIMIZE,
- MOVE,
- RESIZE,
- RESTORE,
- LAST_SIGNAL
-};
-
-static void gail_window_class_init (GailWindowClass *klass);
-
-static void gail_window_init (GailWindow *accessible);
-
-static void gail_window_real_initialize (AtkObject *obj,
- gpointer data);
-static void gail_window_finalize (GObject *object);
-
-static const gchar* gail_window_get_name (AtkObject *accessible);
-
-static AtkObject* gail_window_get_parent (AtkObject *accessible);
-static gint gail_window_get_index_in_parent (AtkObject *accessible);
-static gboolean gail_window_real_focus_gtk (GtkWidget *widget,
- GdkEventFocus *event);
-
-static AtkStateSet* gail_window_ref_state_set (AtkObject *accessible);
-static AtkRelationSet* gail_window_ref_relation_set (AtkObject *accessible);
-static void gail_window_real_notify_gtk (GObject *obj,
- GParamSpec *pspec);
-static gint gail_window_get_mdi_zorder (AtkComponent *component);
-
-static gboolean gail_window_state_event_gtk (GtkWidget *widget,
- GdkEventWindowState *event);
-
-/* atkcomponent.h */
-static void atk_component_interface_init (AtkComponentIface *iface);
-
-static void gail_window_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type);
-static void gail_window_get_size (AtkComponent *component,
- gint *width,
- gint *height);
-
-static guint gail_window_signals [LAST_SIGNAL] = { 0, };
-
-G_DEFINE_TYPE_WITH_CODE (GailWindow, gail_window, GAIL_TYPE_CONTAINER,
- G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init))
-
-static void
-gail_window_class_init (GailWindowClass *klass)
-{
- GailWidgetClass *widget_class;
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-
- gobject_class->finalize = gail_window_finalize;
-
- widget_class = (GailWidgetClass*)klass;
- widget_class->focus_gtk = gail_window_real_focus_gtk;
- widget_class->notify_gtk = gail_window_real_notify_gtk;
-
- class->get_name = gail_window_get_name;
- class->get_parent = gail_window_get_parent;
- class->get_index_in_parent = gail_window_get_index_in_parent;
- class->ref_relation_set = gail_window_ref_relation_set;
- class->ref_state_set = gail_window_ref_state_set;
- class->initialize = gail_window_real_initialize;
-
- gail_window_signals [ACTIVATE] =
- g_signal_new ("activate",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, /* default signal handler */
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- gail_window_signals [CREATE] =
- g_signal_new ("create",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, /* default signal handler */
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- gail_window_signals [DEACTIVATE] =
- g_signal_new ("deactivate",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, /* default signal handler */
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- gail_window_signals [DESTROY] =
- g_signal_new ("destroy",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, /* default signal handler */
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- gail_window_signals [MAXIMIZE] =
- g_signal_new ("maximize",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, /* default signal handler */
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- gail_window_signals [MINIMIZE] =
- g_signal_new ("minimize",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, /* default signal handler */
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- gail_window_signals [MOVE] =
- g_signal_new ("move",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, /* default signal handler */
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- gail_window_signals [RESIZE] =
- g_signal_new ("resize",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, /* default signal handler */
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- gail_window_signals [RESTORE] =
- g_signal_new ("restore",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, /* default signal handler */
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-static void
-gail_window_init (GailWindow *accessible)
-{
-}
-
-static void
-gail_window_real_initialize (AtkObject *obj,
- gpointer data)
-{
- GtkWidget *widget = GTK_WIDGET (data);
- GailWindow *window;
-
- /*
- * A GailWindow can be created for a GtkHandleBox or a GtkWindow
- */
- if (!GTK_IS_WINDOW (widget) &&
- !GTK_IS_HANDLE_BOX (widget))
- gail_return_if_fail (FALSE);
-
- ATK_OBJECT_CLASS (gail_window_parent_class)->initialize (obj, data);
-
- window = GAIL_WINDOW (obj);
- window->name_change_handler = 0;
- window->previous_name = g_strdup (gtk_window_get_title (GTK_WINDOW (data)));
-
- g_signal_connect (data,
- "window_state_event",
- G_CALLBACK (gail_window_state_event_gtk),
- NULL);
- g_object_set_data (G_OBJECT (obj), "atk-component-layer",
- GINT_TO_POINTER (ATK_LAYER_WINDOW));
-
- if (GTK_IS_FILE_CHOOSER_DIALOG (widget))
- obj->role = ATK_ROLE_FILE_CHOOSER;
- else if (GTK_IS_COLOR_SELECTION_DIALOG (widget))
- obj->role = ATK_ROLE_COLOR_CHOOSER;
- else if (GTK_IS_FONT_SELECTION_DIALOG (widget))
- obj->role = ATK_ROLE_FONT_CHOOSER;
- else if (GTK_IS_MESSAGE_DIALOG (widget))
- obj->role = ATK_ROLE_ALERT;
- else if (GTK_IS_DIALOG (widget))
- obj->role = ATK_ROLE_DIALOG;
- else
- {
- const gchar *name;
-
- name = gtk_widget_get_name (widget);
-
- if (!g_strcmp0 (name, "gtk-tooltip"))
- obj->role = ATK_ROLE_TOOL_TIP;
-#ifdef GDK_WINDOWING_X11
- else if (GTK_IS_PLUG (widget))
- obj->role = ATK_ROLE_PANEL;
-#endif
- else if (gtk_window_get_window_type (GTK_WINDOW (widget)) == GTK_WINDOW_POPUP)
- obj->role = ATK_ROLE_WINDOW;
- else
- obj->role = ATK_ROLE_FRAME;
- }
-
- /*
- * Notify that tooltip is showing
- */
- if (obj->role == ATK_ROLE_TOOL_TIP &&
- gtk_widget_get_mapped (widget))
- atk_object_notify_state_change (obj, ATK_STATE_SHOWING, 1);
-}
-
-static void
-gail_window_finalize (GObject *object)
-{
- GailWindow* window = GAIL_WINDOW (object);
-
- if (window->name_change_handler)
- {
- g_source_remove (window->name_change_handler);
- window->name_change_handler = 0;
- }
- if (window->previous_name)
- {
- g_free (window->previous_name);
- window->previous_name = NULL;
- }
-
- G_OBJECT_CLASS (gail_window_parent_class)->finalize (object);
-}
-
-static const gchar*
-gail_window_get_name (AtkObject *accessible)
-{
- const gchar* name;
-
- name = ATK_OBJECT_CLASS (gail_window_parent_class)->get_name (accessible);
- if (name == NULL)
- {
- /*
- * Get the window title if it exists
- */
- GtkWidget* widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- gail_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- if (GTK_IS_WINDOW (widget))
- {
- GtkWindow *window = GTK_WINDOW (widget);
-
- name = gtk_window_get_title (window);
- if (name == NULL &&
- accessible->role == ATK_ROLE_TOOL_TIP)
- {
- GtkWidget *child;
-
- child = gtk_bin_get_child (GTK_BIN (window));
- /* could be some kind of egg notification bubble thingy? */
-
- /* Handle new GTK+ GNOME 2.20 tooltips */
- if (GTK_IS_ALIGNMENT(child))
- {
- child = gtk_bin_get_child (GTK_BIN (child));
- if (GTK_IS_BOX(child))
- {
- GList *children;
- guint count;
- children = gtk_container_get_children (GTK_CONTAINER (child));
- count = g_list_length (children);
- if (count == 2)
- {
- child = (GtkWidget *) g_list_nth_data (children, 1);
- }
- g_list_free (children);
- }
- }
-
- if (!GTK_IS_LABEL (child))
- {
- g_message ("ATK_ROLE_TOOLTIP object found, but doesn't look like a tooltip.");
- return NULL;
- }
- name = gtk_label_get_text (GTK_LABEL (child));
- }
- }
- }
- return name;
-}
-
-static AtkObject*
-gail_window_get_parent (AtkObject *accessible)
-{
- AtkObject* parent;
-
- parent = ATK_OBJECT_CLASS (gail_window_parent_class)->get_parent (accessible);
-
- return parent;
-}
-
-static gint
-gail_window_get_index_in_parent (AtkObject *accessible)
-{
- GtkWidget* widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
- AtkObject* atk_obj = atk_get_root ();
- gint index = -1;
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return -1;
-
- gail_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
-
- index = ATK_OBJECT_CLASS (gail_window_parent_class)->get_index_in_parent (accessible);
- if (index != -1)
- return index;
-
- if (GTK_IS_WINDOW (widget))
- {
- GtkWindow *window = GTK_WINDOW (widget);
- if (GAIL_IS_TOPLEVEL (atk_obj))
- {
- GailToplevel* toplevel = GAIL_TOPLEVEL (atk_obj);
- index = g_list_index (toplevel->window_list, window);
- }
- else
- {
- int i, sibling_count = atk_object_get_n_accessible_children (atk_obj);
- for (i = 0; i < sibling_count && index == -1; ++i)
- {
- AtkObject *child = atk_object_ref_accessible_child (atk_obj, i);
- if (accessible == child) index = i;
- g_object_unref (G_OBJECT (child));
- }
- }
- }
- return index;
-}
-
-static gboolean
-gail_window_real_focus_gtk (GtkWidget *widget,
- GdkEventFocus *event)
-{
- AtkObject* obj;
-
- obj = gtk_widget_get_accessible (widget);
- atk_object_notify_state_change (obj, ATK_STATE_ACTIVE, event->in);
-
- return FALSE;
-}
-
-static AtkRelationSet*
-gail_window_ref_relation_set (AtkObject *obj)
-{
- GtkWidget *widget;
- AtkRelationSet *relation_set;
- AtkObject *array[1];
- AtkRelation* relation;
- GtkWidget *current_widget;
-
- gail_return_val_if_fail (GAIL_IS_WIDGET (obj), NULL);
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (widget == NULL)
- /*
- * State is defunct
- */
- return NULL;
-
- relation_set = ATK_OBJECT_CLASS (gail_window_parent_class)->ref_relation_set (obj);
-
- if (atk_object_get_role (obj) == ATK_ROLE_TOOL_TIP)
- {
- relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_POPUP_FOR);
-
- if (relation)
- {
- atk_relation_set_remove (relation_set, relation);
- }
- if (gtk_widget_get_visible(widget) && FALSE /* FIXME gtk_tooltips_get_info_from_tip_window (GTK_WINDOW (widget), NULL, ¤t_widget) */)
- {
- array [0] = gtk_widget_get_accessible (current_widget);
-
- relation = atk_relation_new (array, 1, ATK_RELATION_POPUP_FOR);
- atk_relation_set_add (relation_set, relation);
- g_object_unref (relation);
- }
- }
- return relation_set;
-}
-
-static AtkStateSet*
-gail_window_ref_state_set (AtkObject *accessible)
-{
- AtkStateSet *state_set;
- GtkWidget *widget;
- GtkWindow *window;
- GdkWindow *gdk_window;
- GdkWindowState state;
-
- state_set = ATK_OBJECT_CLASS (gail_window_parent_class)->ref_state_set (accessible);
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
-
- if (widget == NULL)
- return state_set;
-
- window = GTK_WINDOW (widget);
-
- if (gtk_window_has_toplevel_focus (window) && gtk_window_is_active (window))
- atk_state_set_add_state (state_set, ATK_STATE_ACTIVE);
-
- gdk_window = gtk_widget_get_window (widget);
- if (window)
- {
- state = gdk_window_get_state (gdk_window);
- if (state & GDK_WINDOW_STATE_ICONIFIED)
- atk_state_set_add_state (state_set, ATK_STATE_ICONIFIED);
- }
- if (gtk_window_get_modal (window))
- atk_state_set_add_state (state_set, ATK_STATE_MODAL);
-
- if (gtk_window_get_resizable (window))
- atk_state_set_add_state (state_set, ATK_STATE_RESIZABLE);
-
- return state_set;
-}
-
-static gboolean
-idle_notify_name_change (gpointer data)
-{
- GailWindow *window;
- AtkObject *obj;
-
- window = GAIL_WINDOW (data);
- window->name_change_handler = 0;
- if (gtk_accessible_get_widget (GTK_ACCESSIBLE (window)) == NULL)
- return FALSE;
-
- obj = ATK_OBJECT (window);
- if (obj->name == NULL)
- {
- /*
- * The title has changed so notify a change in accessible-name
- */
- g_object_notify (G_OBJECT (obj), "accessible-name");
- }
- g_signal_emit_by_name (obj, "visible_data_changed");
-
- return FALSE;
-}
-
-static void
-gail_window_real_notify_gtk (GObject *obj,
- GParamSpec *pspec)
-{
- GtkWidget *widget = GTK_WIDGET (obj);
- AtkObject* atk_obj = gtk_widget_get_accessible (widget);
- GailWindow *window = GAIL_WINDOW (atk_obj);
- const gchar *name;
- gboolean name_changed = FALSE;
-
- if (strcmp (pspec->name, "title") == 0)
- {
- name = gtk_window_get_title (GTK_WINDOW (widget));
- if (name)
- {
- if (window->previous_name == NULL ||
- strcmp (name, window->previous_name) != 0)
- name_changed = TRUE;
- }
- else if (window->previous_name != NULL)
- name_changed = TRUE;
-
- if (name_changed)
- {
- g_free (window->previous_name);
- window->previous_name = g_strdup (name);
-
- if (window->name_change_handler == 0)
- window->name_change_handler = gdk_threads_add_idle (idle_notify_name_change, atk_obj);
- }
- }
- else
- GAIL_WIDGET_CLASS (gail_window_parent_class)->notify_gtk (obj, pspec);
-}
-
-static gboolean
-gail_window_state_event_gtk (GtkWidget *widget,
- GdkEventWindowState *event)
-{
- AtkObject* obj;
-
- obj = gtk_widget_get_accessible (widget);
- atk_object_notify_state_change (obj, ATK_STATE_ICONIFIED,
- (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0);
- return FALSE;
-}
-
-static void
-atk_component_interface_init (AtkComponentIface *iface)
-{
- iface->get_extents = gail_window_get_extents;
- iface->get_size = gail_window_get_size;
- iface->get_mdi_zorder = gail_window_get_mdi_zorder;
-}
-
-static void
-gail_window_get_extents (AtkComponent *component,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coord_type)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
- GdkRectangle rect;
- gint x_toplevel, y_toplevel;
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return;
-
- gail_return_if_fail (GTK_IS_WINDOW (widget));
-
- if (!gtk_widget_is_toplevel (widget))
- {
- AtkComponentIface *parent_iface;
-
- parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
- parent_iface->get_extents (component, x, y, width, height, coord_type);
- return;
- }
-
- gdk_window_get_frame_extents (gtk_widget_get_window (widget),
- &rect);
-
- *width = rect.width;
- *height = rect.height;
- if (!gtk_widget_is_drawable (widget))
- {
- *x = G_MININT;
- *y = G_MININT;
- return;
- }
- *x = rect.x;
- *y = rect.y;
- if (coord_type == ATK_XY_WINDOW)
- {
- gdk_window_get_origin (gtk_widget_get_window (widget),
- &x_toplevel, &y_toplevel);
- *x -= x_toplevel;
- *y -= y_toplevel;
- }
-}
-
-static void
-gail_window_get_size (AtkComponent *component,
- gint *width,
- gint *height)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
- GdkRectangle rect;
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return;
-
- gail_return_if_fail (GTK_IS_WINDOW (widget));
-
- if (!gtk_widget_is_toplevel (widget))
- {
- AtkComponentIface *parent_iface;
-
- parent_iface = (AtkComponentIface *) g_type_interface_peek_parent (ATK_COMPONENT_GET_IFACE (component));
- parent_iface->get_size (component, width, height);
- return;
- }
- gdk_window_get_frame_extents (gtk_widget_get_window (widget), &rect);
-
- *width = rect.width;
- *height = rect.height;
-}
-
-#if defined (GDK_WINDOWING_X11)
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <gdk/x11/gdkx.h>
-
-/* _NET_CLIENT_LIST_STACKING monitoring */
-
-typedef struct {
- Window *stacked_windows;
- int stacked_windows_len;
- GdkWindow *root_window;
- guint update_handler;
- int *desktop;
- guint update_desktop_handler;
- gboolean *desktop_changed;
-
- guint screen_initialized : 1;
- guint update_stacked_windows : 1;
-} GailScreenInfo;
-
-static GailScreenInfo *gail_screens = NULL;
-static int num_screens = 0;
-static Atom _net_client_list_stacking = None;
-static Atom _net_wm_desktop = None;
-
-static gint
-get_window_desktop (Window window)
-{
- Atom ret_type;
- int format;
- gulong nitems;
- gulong bytes_after;
- guchar *cardinals;
- int error;
- int result;
- int desktop;
-
- if (_net_wm_desktop == None)
- _net_wm_desktop =
- XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_WM_DESKTOP", False);
-
- gdk_error_trap_push ();
- result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), window, _net_wm_desktop,
- 0, G_MAXLONG,
- False, XA_CARDINAL,
- &ret_type, &format, &nitems,
- &bytes_after, &cardinals);
- error = gdk_error_trap_pop();
- /* nitems < 1 will occur if the property is not set */
- if (error != Success || result != Success || nitems < 1)
- return -1;
-
- desktop = *cardinals;
-
- XFree (cardinals);
- if (nitems != 1)
- return -1;
- return desktop;
-}
-
-static void
-free_screen_info (GailScreenInfo *info)
-{
- if (info->stacked_windows)
- XFree (info->stacked_windows);
- if (info->desktop)
- g_free (info->desktop);
- if (info->desktop_changed)
- g_free (info->desktop_changed);
-
- info->stacked_windows = NULL;
- info->stacked_windows_len = 0;
- info->desktop = NULL;
- info->desktop_changed = NULL;
-}
-
-static gboolean
-get_stacked_windows (GailScreenInfo *info)
-{
- Atom ret_type;
- int format;
- gulong nitems;
- gulong bytes_after;
- guchar *data;
- int error;
- int result;
- int i;
- int j;
- int *desktops;
- gboolean *desktops_changed;
-
- if (_net_client_list_stacking == None)
- _net_client_list_stacking =
- XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_CLIENT_LIST_STACKING", False);
-
- gdk_error_trap_push ();
- ret_type = None;
- result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
- GDK_WINDOW_XID (info->root_window),
- _net_client_list_stacking,
- 0, G_MAXLONG,
- False, XA_WINDOW, &ret_type, &format, &nitems,
- &bytes_after, &data);
- error = gdk_error_trap_pop ();
- /* nitems < 1 will occur if the property is not set */
- if (error != Success || result != Success || nitems < 1)
- {
- free_screen_info (info);
- return FALSE;
- }
-
- if (ret_type != XA_WINDOW)
- {
- XFree (data);
- free_screen_info (info);
- return FALSE;
- }
-
- desktops = g_malloc0 (nitems * sizeof (int));
- desktops_changed = g_malloc0 (nitems * sizeof (gboolean));
- for (i = 0; i < nitems; i++)
- {
- gboolean window_found = FALSE;
-
- for (j = 0; j < info->stacked_windows_len; j++)
- {
- if (info->stacked_windows [j] == data [i])
- {
- desktops [i] = info->desktop [j];
- desktops_changed [i] = info->desktop_changed [j];
- window_found = TRUE;
- break;
- }
- }
- if (!window_found)
- {
- desktops [i] = get_window_desktop (data [i]);
- desktops_changed [i] = FALSE;
- }
- }
- free_screen_info (info);
- info->stacked_windows = (Window*) data;
- info->stacked_windows_len = nitems;
- info->desktop = desktops;
- info->desktop_changed = desktops_changed;
-
- return TRUE;
-}
-
-static gboolean
-update_screen_info (gpointer data)
-{
- int screen_n = GPOINTER_TO_INT (data);
-
- gail_screens [screen_n].update_handler = 0;
- gail_screens [screen_n].update_stacked_windows = FALSE;
-
- get_stacked_windows (&gail_screens [screen_n]);
-
- return FALSE;
-}
-
-static gboolean
-update_desktop_info (gpointer data)
-{
- int screen_n = GPOINTER_TO_INT (data);
- GailScreenInfo *info;
- int i;
-
- info = &gail_screens [screen_n];
- info->update_desktop_handler = 0;
-
- for (i = 0; i < info->stacked_windows_len; i++)
- {
- if (info->desktop_changed [i])
- {
- info->desktop [i] = get_window_desktop (info->stacked_windows [i]);
- info->desktop_changed [i] = FALSE;
- }
- }
-
- return FALSE;
-}
-
-static GdkFilterReturn
-filter_func (GdkXEvent *gdkxevent,
- GdkEvent *event,
- gpointer data)
-{
- XEvent *xevent = gdkxevent;
-
- if (xevent->type == PropertyNotify)
- {
- if (xevent->xproperty.atom == _net_client_list_stacking)
- {
- int screen_n;
- GdkWindow *window;
-
- window = event->any.window;
-
- if (window)
- {
- screen_n = gdk_screen_get_number (gdk_window_get_screen (window));
-
- gail_screens [screen_n].update_stacked_windows = TRUE;
- if (!gail_screens [screen_n].update_handler)
- {
- gail_screens [screen_n].update_handler = gdk_threads_add_idle (update_screen_info,
- GINT_TO_POINTER (screen_n));
- }
- }
- }
- else if (xevent->xproperty.atom == _net_wm_desktop)
- {
- int i;
- int j;
- GailScreenInfo *info;
-
- for (i = 0; i < num_screens; i++)
- {
- info = &gail_screens [i];
- for (j = 0; j < info->stacked_windows_len; j++)
- {
- if (xevent->xany.window == info->stacked_windows [j])
- {
- info->desktop_changed [j] = TRUE;
- if (!info->update_desktop_handler)
- {
- info->update_desktop_handler = gdk_threads_add_idle (update_desktop_info,
- GINT_TO_POINTER (i));
- }
- break;
- }
- }
- }
- }
- }
- return GDK_FILTER_CONTINUE;
-}
-
-static void
-display_closed (GdkDisplay *display,
- gboolean is_error)
-{
- int i;
-
- for (i = 0; i < num_screens; i++)
- {
- if (gail_screens [i].update_handler)
- {
- g_source_remove (gail_screens [i].update_handler);
- gail_screens [i].update_handler = 0;
- }
-
- if (gail_screens [i].update_desktop_handler)
- {
- g_source_remove (gail_screens [i].update_desktop_handler);
- gail_screens [i].update_desktop_handler = 0;
- }
-
- free_screen_info (&gail_screens [i]);
- }
-
- g_free (gail_screens);
- gail_screens = NULL;
- num_screens = 0;
-}
-
-static void
-init_gail_screens (void)
-{
- GdkDisplay *display;
-
- display = gdk_display_get_default ();
-
- num_screens = gdk_display_get_n_screens (display);
-
- gail_screens = g_new0 (GailScreenInfo, num_screens);
- gdk_window_add_filter (NULL, filter_func, NULL);
-
- g_signal_connect (display, "closed", G_CALLBACK (display_closed), NULL);
-}
-
-static void
-init_gail_screen (GdkScreen *screen,
- int screen_n)
-{
- XWindowAttributes attrs;
-
- gail_screens [screen_n].root_window = gdk_screen_get_root_window (screen);
-
- get_stacked_windows (&gail_screens [screen_n]);
-
- XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
- GDK_WINDOW_XID (gail_screens [screen_n].root_window),
- &attrs);
-
- XSelectInput (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
- GDK_WINDOW_XID (gail_screens [screen_n].root_window),
- attrs.your_event_mask | PropertyChangeMask);
-
- gail_screens [screen_n].screen_initialized = TRUE;
-}
-
-static GailScreenInfo *
-get_screen_info (GdkScreen *screen)
-{
- int screen_n;
-
- gail_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
- screen_n = gdk_screen_get_number (screen);
-
- if (gail_screens && gail_screens [screen_n].screen_initialized)
- return &gail_screens [screen_n];
-
- if (!gail_screens)
- init_gail_screens ();
-
- g_assert (gail_screens != NULL);
-
- init_gail_screen (screen, screen_n);
-
- g_assert (gail_screens [screen_n].screen_initialized);
-
- return &gail_screens [screen_n];
-}
-
-static gint
-get_window_zorder (GdkWindow *window)
-{
- GailScreenInfo *info;
- Window xid;
- int i;
- int zorder;
- int w_desktop;
-
- gail_return_val_if_fail (GDK_IS_WINDOW (window), -1);
-
- info = get_screen_info (gdk_window_get_screen (window));
-
- gail_return_val_if_fail (info->stacked_windows != NULL, -1);
-
- xid = GDK_WINDOW_XID (window);
-
- w_desktop = -1;
- for (i = 0; i < info->stacked_windows_len; i++)
- {
- if (info->stacked_windows [i] == xid)
- {
- w_desktop = info->desktop[i];
- break;
- }
- }
- if (w_desktop < 0)
- return w_desktop;
-
- zorder = 0;
- for (i = 0; i < info->stacked_windows_len; i++)
- {
- if (info->stacked_windows [i] == xid)
- {
- return zorder;
- }
- else
- {
- if (info->desktop[i] == w_desktop)
- zorder++;
- }
- }
-
- return -1;
-}
-
-static gint
-gail_window_get_mdi_zorder (AtkComponent *component)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return -1;
-
- gail_return_val_if_fail (GTK_IS_WINDOW (widget), -1);
-
- return get_window_zorder (gtk_widget_get_window (widget));
-}
-
-#elif defined (GDK_WINDOWING_WIN32)
-
-static gint
-gail_window_get_mdi_zorder (AtkComponent *component)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return -1;
-
- gail_return_val_if_fail (GTK_IS_WINDOW (widget), -1);
-
- return 0; /* Punt, FIXME */
-}
-
-#else
-
-static gint
-gail_window_get_mdi_zorder (AtkComponent *component)
-{
- GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (component));
-
- if (widget == NULL)
- /*
- * State is defunct
- */
- return -1;
-
- gail_return_val_if_fail (GTK_IS_WINDOW (widget), -1);
-
- return 0; /* Punt, FIXME */
-}
-
-#endif
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_WINDOW_H__
-#define __GAIL_WINDOW_H__
-
-#include "gailcontainer.h"
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_WINDOW (gail_window_get_type ())
-#define GAIL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_WINDOW, GailWindow))
-#define GAIL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_WINDOW, GailWindowClass))
-#define GAIL_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_WINDOW))
-#define GAIL_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_WINDOW))
-#define GAIL_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_WINDOW, GailWindowClass))
-
-typedef struct _GailWindow GailWindow;
-typedef struct _GailWindowClass GailWindowClass;
-
-struct _GailWindow
-{
- GailContainer parent;
-
- guint name_change_handler;
- gchar *previous_name;
-};
-
-GType gail_window_get_type (void);
-
-struct _GailWindowClass
-{
- GailContainerClass parent_class;
-};
-
-G_END_DECLS
-
-#endif /* __GAIL_WINDOW_H__ */
+++ /dev/null
-include $(top_srcdir)/Makefile.decl
-
-EXTRA_DIST += gailutil.def
-if PLATFORM_WIN32
-no_undefined = -no-undefined
-endif
-if OS_WIN32
-export_symbols = -export-symbols $(srcdir)/gailutil.def
-install-def-file: gailutil.def
- $(INSTALL) $(srcdir)/gailutil.def $(DESTDIR)$(libdir)
-uninstall-def-file:
- -rm $(DESTDIR)$(libdir)/gailutil.def
-else
-install-def-file:
-uninstall-def-file:
-endif
-
-if MS_LIB_AVAILABLE
-noinst_DATA = gailutil.lib
-
-install-ms-lib:
- $(INSTALL) gailutil.lib $(DESTDIR)$(libdir)
-
-uninstall-ms-lib:
- -rm $(DESTDIR)$(libdir)/gailutil.lib
-else
-install-ms-lib:
-uninstall-ms-lib:
-endif
-
-
-lib_LTLIBRARIES = libgailutil-3.la
-
-util_c_sources = \
- gailmisc.c \
- gailtextutil.c
-
-libgailutilincludedir=$(includedir)/gail-3.0/libgail-util
-
-util_public_h_sources = \
- gailmisc.h \
- gailtextutil.h \
- gail-util.h
-
-libgailutil_3_la_SOURCES = \
- $(util_c_sources)
-
-libgailutilinclude_HEADERS = \
- $(util_public_h_sources)
-
-libgailutil_3_la_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/gdk \
- -I$(top_builddir)/gdk \
- -I$(top_srcdir)/gtk \
- -I$(top_builddir)/gtk \
- $(AM_CPPFLAGS) \
- -DGDK_DISABLE_DEPRECATED\
- -DGTK_DISABLE_DEPRECATED
-
-libgailutil_3_la_CFLAGS = \
- $(GTK_DEP_CFLAGS) \
- $(GTK_DEBUG_FLAGS) \
- $(AM_CFLAGS)
-
-libgailutil_3_la_LIBADD = \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS)
-
-libgailutil_3_la_LDFLAGS = \
- -version-info $(GAIL_LT_VERSION_INFO) \
- $(no_undefined) \
- $(export_symbols) \
- $(LDFLAGS)
-
-gailutil.lib: libgailutil-3.la gailutil.def
- lib -machine:@LIB_EXE_MACHINE_FLAG@ -name:libgailutil-3.0-$(GAIL_LT_CURRENT_MINUS_AGE).dll -def:gailutil.def -out:$@
-
-install-data-local: install-ms-lib install-def-file
-
-uninstall-local: uninstall-ms-lib uninstall-def-file
-
--include $(top_srcdir)/git.mk
+++ /dev/null
-#include <libgail-util/gailmisc.h>
-#include <libgail-util/gailtextutil.h>
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <gtk/gtk.h>
-#include "gailmisc.h"
-
-/* IMPORTANT!!! This source file does NOT contain the implementation
- * code for AtkUtil - for that code, please see gail/gail.c.
- */
-
-/**
- * SECTION:gailmisc
- * @Short_description: GailMisc is a set of utility functions which may be
- * useful to implementors of Atk interfaces for custom widgets.
- * @Title: GailMisc
- *
- * GailMisc is a set of utility function which are used in the implemementation
- * of Atk interfaces for GTK+ widgets. They may be useful to implementors of
- * Atk interfaces for custom widgets.
- */
-
-
-/**
- * gail_misc_get_extents_from_pango_rectangle:
- * @widget: The widget that contains the PangoLayout, that contains
- * the PangoRectangle
- * @char_rect: The #PangoRectangle from which to calculate extents
- * @x_layout: The x-offset at which the widget displays the
- * PangoLayout that contains the PangoRectangle, relative to @widget
- * @y_layout: The y-offset at which the widget displays the
- * PangoLayout that contains the PangoRectangle, relative to @widget
- * @x: The x-position of the #PangoRectangle relative to @coords
- * @y: The y-position of the #PangoRectangle relative to @coords
- * @width: The width of the #PangoRectangle
- * @height: The height of the #PangoRectangle
- * @coords: An #AtkCoordType enumeration
- *
- * Gets the extents of @char_rect in device coordinates,
- * relative to either top-level window or screen coordinates as
- * specified by @coords.
- **/
-void
-gail_misc_get_extents_from_pango_rectangle (GtkWidget *widget,
- PangoRectangle *char_rect,
- gint x_layout,
- gint y_layout,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords)
-{
- gint x_window, y_window, x_toplevel, y_toplevel;
-
- gail_misc_get_origins (widget, &x_window, &y_window,
- &x_toplevel, &y_toplevel);
-
- *x = (char_rect->x / PANGO_SCALE) + x_layout + x_window;
- *y = (char_rect->y / PANGO_SCALE) + y_layout + y_window;
- if (coords == ATK_XY_WINDOW)
- {
- *x -= x_toplevel;
- *y -= y_toplevel;
- }
- else if (coords != ATK_XY_SCREEN)
- {
- *x = 0;
- *y = 0;
- *height = 0;
- *width = 0;
- return;
- }
- *height = char_rect->height / PANGO_SCALE;
- *width = char_rect->width / PANGO_SCALE;
-
- return;
-}
-
-/**
- * gail_misc_get_index_at_point_in_layout:
- * @widget: A #GtkWidget
- * @layout: The #PangoLayout from which to get the index at the
- * specified point.
- * @x_layout: The x-offset at which the widget displays the
- * #PangoLayout, relative to @widget
- * @y_layout: The y-offset at which the widget displays the
- * #PangoLayout, relative to @widget
- * @x: The x-coordinate relative to @coords at which to
- * calculate the index
- * @y: The y-coordinate relative to @coords at which to
- * calculate the index
- * @coords: An #AtkCoordType enumeration
- *
- * Gets the byte offset at the specified @x and @y in a #PangoLayout.
- *
- * Returns: the byte offset at the specified @x and @y in a
- * #PangoLayout
- **/
-gint
-gail_misc_get_index_at_point_in_layout (GtkWidget *widget,
- PangoLayout *layout,
- gint x_layout,
- gint y_layout,
- gint x,
- gint y,
- AtkCoordType coords)
-{
- gint index, x_window, y_window, x_toplevel, y_toplevel;
- gint x_temp, y_temp;
- gboolean ret;
-
- gail_misc_get_origins (widget, &x_window, &y_window,
- &x_toplevel, &y_toplevel);
- x_temp = x - x_layout - x_window;
- y_temp = y - y_layout - y_window;
- if (coords == ATK_XY_WINDOW)
- {
- x_temp += x_toplevel;
- y_temp += y_toplevel;
- }
- else if (coords != ATK_XY_SCREEN)
- return -1;
-
- ret = pango_layout_xy_to_index (layout,
- x_temp * PANGO_SCALE,
- y_temp * PANGO_SCALE,
- &index, NULL);
- if (!ret)
- {
- if (x_temp < 0 || y_temp < 0)
- index = 0;
- else
- index = -1;
- }
- return index;
-}
-
-/**
- * gail_misc_add_attribute:
- * @attrib_set: The #AtkAttributeSet to add the attribute to
- * @attr: The AtkTextAttrribute which identifies the attribute to be added
- * @value: The attribute value
- *
- * Creates an #AtkAttribute from @attr and @value, and adds it
- * to @attrib_set.
- *
- * Returns: A pointer to the new #AtkAttributeSet.
- **/
-AtkAttributeSet*
-gail_misc_add_attribute (AtkAttributeSet *attrib_set,
- AtkTextAttribute attr,
- gchar *value)
-{
- AtkAttributeSet *return_set;
- AtkAttribute *at = g_malloc (sizeof (AtkAttribute));
- at->name = g_strdup (atk_text_attribute_get_name (attr));
- at->value = value;
- return_set = g_slist_prepend(attrib_set, at);
- return return_set;
-}
-
-/**
- * gail_misc_layout_get_run_attributes:
- * @attrib_set: The #AtkAttributeSet to add the attribute to
- * @layout: The PangoLayout from which the attributes will be obtained
- * @text: The text
- * @offset: The offset at which the attributes are required
- * @start_offset: The start offset of the current run
- * @end_offset: The end offset of the current run
- *
- * Adds the attributes for the run starting at offset to the specified
- * attribute set.
- *
- * Returns: A pointer to the #AtkAttributeSet.
- **/
-AtkAttributeSet*
-gail_misc_layout_get_run_attributes (AtkAttributeSet *attrib_set,
- PangoLayout *layout,
- const gchar *text,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- PangoAttrIterator *iter;
- PangoAttrList *attr;
- PangoAttrString *pango_string;
- PangoAttrInt *pango_int;
- PangoAttrColor *pango_color;
- PangoAttrLanguage *pango_lang;
- PangoAttrFloat *pango_float;
- gint index, start_index, end_index;
- gboolean is_next = TRUE;
- gchar *value = NULL;
- glong len;
-
- len = g_utf8_strlen (text, -1);
- /* Grab the attributes of the PangoLayout, if any */
- if ((attr = pango_layout_get_attributes (layout)) == NULL)
- {
- *start_offset = 0;
- *end_offset = len;
- return attrib_set;
- }
- iter = pango_attr_list_get_iterator (attr);
- /* Get invariant range offsets */
- /* If offset out of range, set offset in range */
- if (offset > len)
- offset = len;
- else if (offset < 0)
- offset = 0;
-
- index = g_utf8_offset_to_pointer (text, offset) - text;
- pango_attr_iterator_range (iter, &start_index, &end_index);
- while (is_next)
- {
- if (index >= start_index && index < end_index)
- {
- *start_offset = g_utf8_pointer_to_offset (text,
- text + start_index);
- if (end_index == G_MAXINT)
- /* Last iterator */
- end_index = len;
-
- *end_offset = g_utf8_pointer_to_offset (text,
- text + end_index);
- break;
- }
- is_next = pango_attr_iterator_next (iter);
- pango_attr_iterator_range (iter, &start_index, &end_index);
- }
- /* Get attributes */
- if ((pango_string = (PangoAttrString*) pango_attr_iterator_get (iter,
- PANGO_ATTR_FAMILY)) != NULL)
- {
- value = g_strdup_printf("%s", pango_string->value);
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_FAMILY_NAME,
- value);
- }
- if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
- PANGO_ATTR_STYLE)) != NULL)
- {
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_STYLE,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, pango_int->value)));
- }
- if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
- PANGO_ATTR_WEIGHT)) != NULL)
- {
- value = g_strdup_printf("%i", pango_int->value);
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_WEIGHT,
- value);
- }
- if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
- PANGO_ATTR_VARIANT)) != NULL)
- {
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_VARIANT,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, pango_int->value)));
- }
- if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
- PANGO_ATTR_STRETCH)) != NULL)
- {
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_STRETCH,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, pango_int->value)));
- }
- if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
- PANGO_ATTR_SIZE)) != NULL)
- {
- value = g_strdup_printf("%i", pango_int->value / PANGO_SCALE);
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_SIZE,
- value);
- }
- if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
- PANGO_ATTR_UNDERLINE)) != NULL)
- {
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_UNDERLINE,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, pango_int->value)));
- }
- if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
- PANGO_ATTR_STRIKETHROUGH)) != NULL)
- {
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_STRIKETHROUGH,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, pango_int->value)));
- }
- if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
- PANGO_ATTR_RISE)) != NULL)
- {
- value = g_strdup_printf("%i", pango_int->value);
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_RISE,
- value);
- }
- if ((pango_lang = (PangoAttrLanguage*) pango_attr_iterator_get (iter,
- PANGO_ATTR_LANGUAGE)) != NULL)
- {
- value = g_strdup( pango_language_to_string( pango_lang->value));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_LANGUAGE,
- value);
- }
- if ((pango_float = (PangoAttrFloat*) pango_attr_iterator_get (iter,
- PANGO_ATTR_SCALE)) != NULL)
- {
- value = g_strdup_printf("%g", pango_float->value);
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_SCALE,
- value);
- }
- if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter,
- PANGO_ATTR_FOREGROUND)) != NULL)
- {
- value = g_strdup_printf ("%u,%u,%u",
- pango_color->color.red,
- pango_color->color.green,
- pango_color->color.blue);
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_FG_COLOR,
- value);
- }
- if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter,
- PANGO_ATTR_BACKGROUND)) != NULL)
- {
- value = g_strdup_printf ("%u,%u,%u",
- pango_color->color.red,
- pango_color->color.green,
- pango_color->color.blue);
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_BG_COLOR,
- value);
- }
- pango_attr_iterator_destroy (iter);
- return attrib_set;
-}
-
-/**
- * gail_misc_get_default_attributes:
- * @attrib_set: The #AtkAttributeSet to add the attribute to
- * @layout: The PangoLayout from which the attributes will be obtained
- * @widget: The GtkWidget for which the default attributes are required.
- *
- * Adds the default attributes to the specified attribute set.
- *
- * Returns: A pointer to the #AtkAttributeSet.
- **/
-AtkAttributeSet*
-gail_misc_get_default_attributes (AtkAttributeSet *attrib_set,
- PangoLayout *layout,
- GtkWidget *widget)
-{
- PangoContext *context;
- GtkStyleContext *style_context;
- gint int_value;
- PangoWrapMode mode;
- GdkRGBA color;
- gchar *value;
-
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_DIRECTION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
- gtk_widget_get_direction (widget))));
-
- context = pango_layout_get_context (layout);
- if (context)
- {
- PangoLanguage* language;
- PangoFontDescription* font;
-
- language = pango_context_get_language (context);
- if (language)
- {
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_LANGUAGE,
- g_strdup (pango_language_to_string (language)));
- }
- font = pango_context_get_font_description (context);
- if (font)
- {
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_STYLE,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE,
- pango_font_description_get_style (font))));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_VARIANT,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT,
- pango_font_description_get_variant (font))));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_STRETCH,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH,
- pango_font_description_get_stretch (font))));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_FAMILY_NAME,
- g_strdup (pango_font_description_get_family (font)));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_WEIGHT,
- g_strdup_printf ("%d",
- pango_font_description_get_weight (font)));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_SIZE,
- g_strdup_printf ("%i",
- pango_font_description_get_size (font) / PANGO_SCALE));
- }
- }
- if (pango_layout_get_justify (layout))
- {
- int_value = 3;
- }
- else
- {
- PangoAlignment align;
-
- align = pango_layout_get_alignment (layout);
- if (align == PANGO_ALIGN_LEFT)
- int_value = 0;
- else if (align == PANGO_ALIGN_CENTER)
- int_value = 2;
- else /* if (align == PANGO_ALIGN_RIGHT) */
- int_value = 1;
- }
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_JUSTIFICATION,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION,
- int_value)));
- mode = pango_layout_get_wrap (layout);
- if (mode == PANGO_WRAP_WORD)
- int_value = 2;
- else /* if (mode == PANGO_WRAP_CHAR) */
- int_value = 1;
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_WRAP_MODE,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE,
- int_value)));
-
- style_context = gtk_widget_get_style_context (widget);
-
- gtk_style_context_get_background_color (style_context, 0, &color);
- value = g_strdup_printf ("%u,%u,%u",
- (guint) ceil (color.red * 65536 - color.red),
- (guint) ceil (color.green * 65536 - color.green),
- (guint) ceil (color.blue * 65536 - color.blue));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_BG_COLOR,
- value);
-
- gtk_style_context_get_color (style_context, 0, &color);
- value = g_strdup_printf ("%u,%u,%u",
- (guint) ceil (color.red * 65536 - color.red),
- (guint) ceil (color.green * 65536 - color.green),
- (guint) ceil (color.blue * 65536 - color.blue));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_FG_COLOR,
- value);
-
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_FG_STIPPLE,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_FG_STIPPLE,
- 0)));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_BG_STIPPLE,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_STIPPLE,
- 0)));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_STRIKETHROUGH,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH,
- 0)));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_UNDERLINE,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE,
- 0)));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_RISE,
- g_strdup_printf ("%i", 0));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_SCALE,
- g_strdup_printf ("%g", 1.0));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_BG_FULL_HEIGHT,
- g_strdup_printf ("%i", 0));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP,
- g_strdup_printf ("%i", 0));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_PIXELS_BELOW_LINES,
- g_strdup_printf ("%i", 0));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_PIXELS_ABOVE_LINES,
- g_strdup_printf ("%i", 0));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_EDITABLE,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE,
- 0)));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_INVISIBLE,
- g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_INVISIBLE,
- 0)));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_INDENT,
- g_strdup_printf ("%i", 0));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_RIGHT_MARGIN,
- g_strdup_printf ("%i", 0));
- attrib_set = gail_misc_add_attribute (attrib_set,
- ATK_TEXT_ATTR_LEFT_MARGIN,
- g_strdup_printf ("%i", 0));
- return attrib_set;
-}
-
-/**
- * gail_misc_get_origins:
- * @widget: a #GtkWidget
- * @x_window: the x-origin of the widget->window
- * @y_window: the y-origin of the widget->window
- * @x_toplevel: the x-origin of the toplevel window for widget->window
- * @y_toplevel: the y-origin of the toplevel window for widget->window
- *
- * Gets the origin of the widget window, and the origin of the
- * widgets top-level window.
- **/
-void
-gail_misc_get_origins (GtkWidget *widget,
- gint *x_window,
- gint *y_window,
- gint *x_toplevel,
- gint *y_toplevel)
-{
- GdkWindow *window;
-
- if (GTK_IS_TREE_VIEW (widget))
- window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget));
- else
- window = gtk_widget_get_window (widget);
-
- gdk_window_get_origin (window, x_window, y_window);
- window = gdk_window_get_toplevel (gtk_widget_get_window (widget));
- gdk_window_get_origin (window, x_toplevel, y_toplevel);
-}
-
-/**
- * gail_misc_buffer_get_run_attributes:
- * @buffer: The #GtkTextBuffer for which the attributes will be obtained
- * @offset: The offset at which the attributes are required
- * @start_offset: The start offset of the current run
- * @end_offset: The end offset of the current run
- *
- * Creates an AtkAttributeSet which contains the attributes for the
- * run starting at offset.
- *
- * Returns: A pointer to the #AtkAttributeSet.
- **/
-AtkAttributeSet*
-gail_misc_buffer_get_run_attributes (GtkTextBuffer *buffer,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkTextIter iter;
- AtkAttributeSet *attrib_set = NULL;
- AtkAttribute *at;
- GSList *tags, *temp_tags;
- gdouble scale = 1;
- gboolean val_set = FALSE;
-
- gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
-
- gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
- *end_offset = gtk_text_iter_get_offset (&iter);
-
- gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
- *start_offset = gtk_text_iter_get_offset (&iter);
-
- gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
-
- tags = gtk_text_iter_get_tags (&iter);
- tags = g_slist_reverse (tags);
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "style-set", &val_set, NULL);
- if (val_set)
- {
- PangoStyle style;
- gchar *value;
-
- g_object_get (tag, "style", &style, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, style));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STYLE, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "variant-set", &val_set, NULL);
- if (val_set)
- {
- PangoVariant variant;
- gchar *value;
-
- g_object_get (tag, "variant", &variant, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, variant));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "stretch-set", &val_set, NULL);
- if (val_set)
- {
- PangoStretch stretch;
- gchar *value;
-
- g_object_get (tag, "stretch", &stretch, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, stretch));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "justification-set", &val_set, NULL);
- if (val_set)
- {
- GtkJustification justification;
- gchar *value;
-
- g_object_get (tag, "justification", &justification, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justification));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
- GtkTextDirection direction;
-
- g_object_get (tag, "direction", &direction, NULL);
-
- if (direction != GTK_TEXT_DIR_NONE)
- {
- gchar *value;
- val_set = TRUE;
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, direction));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "wrap-mode-set", &val_set, NULL);
- if (val_set)
- {
- GtkWrapMode wrap_mode;
- gchar *value;
-
- g_object_get (tag, "wrap-mode", &wrap_mode, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, wrap_mode));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "foreground-set", &val_set, NULL);
- if (val_set)
- {
- GdkRGBA *rgba;
- gchar *value;
-
- g_object_get (tag, "foreground-rgba", &rgba, NULL);
- value = g_strdup_printf ("%u,%u,%u",
- (guint) rgba->red * 65535,
- (guint) rgba->green * 65535,
- (guint) rgba->blue * 65535);
- gdk_rgba_free (rgba);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "background-set", &val_set, NULL);
- if (val_set)
- {
- GdkRGBA *rgba;
- gchar *value;
-
- g_object_get (tag, "background-rgba", &rgba, NULL);
- value = g_strdup_printf ("%u,%u,%u",
- (guint) rgba->red * 65535,
- (guint) rgba->green * 65535,
- (guint) rgba->blue * 65535);
- gdk_rgba_free (rgba);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "family-set", &val_set, NULL);
-
- if (val_set)
- {
- gchar *value;
- g_object_get (tag, "family", &value, NULL);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "language-set", &val_set, NULL);
-
- if (val_set)
- {
- gchar *value;
- g_object_get (tag, "language", &value, NULL);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "weight-set", &val_set, NULL);
-
- if (val_set)
- {
- gint weight;
- gchar *value;
-
- g_object_get (tag, "weight", &weight, NULL);
- value = g_strdup_printf ("%d", weight);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
-
- /*
- * scale is special as the scale is the product of all scale values
- * specified.
- */
- temp_tags = tags;
- while (temp_tags)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
- gboolean scale_set;
-
- g_object_get (tag, "scale-set", &scale_set, NULL);
- if (scale_set)
- {
- gdouble font_scale;
-
- g_object_get (tag, "scale", &font_scale, NULL);
- val_set = TRUE;
- scale *= font_scale;
- }
- temp_tags = temp_tags->next;
- }
- if (val_set)
- {
- at = g_malloc(sizeof(AtkAttribute));
- at->name = g_strdup(atk_text_attribute_get_name (ATK_TEXT_ATTR_SCALE));
- at->value = g_strdup_printf("%g", scale);
- attrib_set = g_slist_prepend(attrib_set, at);
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "size-set", &val_set, NULL);
- if (val_set)
- {
- gint size;
- gchar *value;
- g_object_get (tag, "size", &size, NULL);
- value = g_strdup_printf ("%i", size);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "strikethrough-set", &val_set, NULL);
- if (val_set)
- {
- gboolean strikethrough;
- gchar *value;
- g_object_get (tag, "strikethrough", &strikethrough, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, strikethrough));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "underline-set", &val_set, NULL);
- if (val_set)
- {
- PangoUnderline underline;
- gchar *value;
- g_object_get (tag, "underline", &underline, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, underline));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "rise-set", &val_set, NULL);
- if (val_set)
- {
- gint rise;
- gchar *value;
- g_object_get (tag, "rise", &rise, NULL);
- value = g_strdup_printf ("%i", rise);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "background-full-height-set", &val_set, NULL);
- if (val_set)
- {
- gboolean bg_full_height;
- gchar *value;
- g_object_get (tag, "background-full-height", &bg_full_height, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, bg_full_height));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "pixels-inside-wrap-set", &val_set, NULL);
- if (val_set)
- {
- gint pixels;
- gchar *value;
- g_object_get (tag, "pixels-inside-wrap", &pixels, NULL);
- value = g_strdup_printf ("%i", pixels);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "pixels-below-lines-set", &val_set, NULL);
- if (val_set)
- {
- gint pixels;
- gchar *value;
- g_object_get (tag, "pixels-below-lines", &pixels, NULL);
- value = g_strdup_printf ("%i", pixels);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "pixels-above-lines-set", &val_set, NULL);
- if (val_set)
- {
- gint pixels;
- gchar *value;
- g_object_get (tag, "pixels-above-lines", &pixels, NULL);
- value = g_strdup_printf ("%i", pixels);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "editable-set", &val_set, NULL);
- if (val_set)
- {
- gboolean editable;
- gchar *value;
- g_object_get (tag, "editable", &editable, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, editable));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "invisible-set", &val_set, NULL);
- if (val_set)
- {
- gboolean invisible;
- gchar *value;
- g_object_get (tag, "invisible", &invisible, NULL);
- value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_INVISIBLE, invisible));
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "indent-set", &val_set, NULL);
- if (val_set)
- {
- gint indent;
- gchar *value;
- g_object_get (tag, "indent", &indent, NULL);
- value = g_strdup_printf ("%i", indent);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "right-margin-set", &val_set, NULL);
- if (val_set)
- {
- gint margin;
- gchar *value;
- g_object_get (tag, "right-margin", &margin, NULL);
- value = g_strdup_printf ("%i", margin);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- temp_tags = tags;
- while (temp_tags && !val_set)
- {
- GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
-
- g_object_get (tag, "left-margin-set", &val_set, NULL);
- if (val_set)
- {
- gint margin;
- gchar *value;
- g_object_get (tag, "left-margin", &margin, NULL);
- value = g_strdup_printf ("%i", margin);
- attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
- }
- temp_tags = temp_tags->next;
- }
- val_set = FALSE;
-
- g_slist_free (tags);
- return attrib_set;
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_MISC_H__
-#define __GAIL_MISC_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-#include <pango/pango.h>
-
-G_BEGIN_DECLS
-
-AtkAttributeSet* gail_misc_add_attribute (AtkAttributeSet *attrib_set,
- AtkTextAttribute attr,
- gchar *value);
-AtkAttributeSet* gail_misc_layout_get_run_attributes
- (AtkAttributeSet *attrib_set,
- PangoLayout *layout,
- const gchar *text,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-
-AtkAttributeSet* gail_misc_get_default_attributes (AtkAttributeSet *attrib_set,
- PangoLayout *layout,
- GtkWidget *widget);
-
-void gail_misc_get_extents_from_pango_rectangle
- (GtkWidget *widget,
- PangoRectangle *char_rect,
- gint x_layout,
- gint y_layout,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- AtkCoordType coords);
-
-gint gail_misc_get_index_at_point_in_layout
- (GtkWidget *widget,
- PangoLayout *layout,
- gint x_layout,
- gint y_layout,
- gint x,
- gint y,
- AtkCoordType coords);
-
-void gail_misc_get_origins (GtkWidget *widget,
- gint *x_window,
- gint *y_window,
- gint *x_toplevel,
- gint *y_toplevel);
-
-AtkAttributeSet* gail_misc_buffer_get_run_attributes
- (GtkTextBuffer *buffer,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-
-G_END_DECLS
-
-#endif /*__GAIL_MISC_H__ */
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include "gailtextutil.h"
-
-/**
- * SECTION:gailtextutil
- * @Short_description: GailTextUtil is a utility class which can be used to
- * implement some of the #AtkText functions for accessible objects
- * which implement #AtkText.
- * @Title: GailTextUtil
- *
- * GailTextUtil is a utility class which can be used to implement the
- * #AtkText functions which get text for accessible objects which implement
- * #AtkText.
- *
- * In GAIL it is used by the accsesible objects for #GnomeCanvasText, #GtkEntry,
- * #GtkLabel, #GtkCellRendererText and #GtkTextView.
- */
-
-static void gail_text_util_class_init (GailTextUtilClass *klass);
-
-static void gail_text_util_init (GailTextUtil *textutil);
-static void gail_text_util_finalize (GObject *object);
-
-
-static void get_pango_text_offsets (PangoLayout *layout,
- GtkTextBuffer *buffer,
- GailOffsetType function,
- AtkTextBoundary boundary_type,
- gint offset,
- gint *start_offset,
- gint *end_offset,
- GtkTextIter *start_iter,
- GtkTextIter *end_iter);
-static GObjectClass *parent_class = NULL;
-
-GType
-gail_text_util_get_type(void)
-{
- static GType type = 0;
-
- if (!type)
- {
- const GTypeInfo tinfo =
- {
- sizeof (GailTextUtilClass),
- (GBaseInitFunc) NULL, /* base init */
- (GBaseFinalizeFunc) NULL, /* base finalize */
- (GClassInitFunc) gail_text_util_class_init,
- (GClassFinalizeFunc) NULL, /* class finalize */
- NULL, /* class data */
- sizeof(GailTextUtil),
- 0, /* nb preallocs */
- (GInstanceInitFunc) gail_text_util_init,
- NULL, /* value table */
- };
-
- type = g_type_register_static (G_TYPE_OBJECT, "GailTextUtil", &tinfo, 0);
- }
- return type;
-}
-
-/**
- * gail_text_util_new:
- *
- * This function creates a new GailTextUtil object.
- *
- * Returns: the GailTextUtil object
- **/
-GailTextUtil*
-gail_text_util_new (void)
-{
- return GAIL_TEXT_UTIL (g_object_new (GAIL_TYPE_TEXT_UTIL, NULL));
-}
-
-static void
-gail_text_util_init (GailTextUtil *textutil)
-{
- textutil->buffer = NULL;
-}
-
-static void
-gail_text_util_class_init (GailTextUtilClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gail_text_util_finalize;
-}
-
-static void
-gail_text_util_finalize (GObject *object)
-{
- GailTextUtil *textutil = GAIL_TEXT_UTIL (object);
-
- if (textutil->buffer)
- g_object_unref (textutil->buffer);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/**
- * gail_text_util_text_setup:
- * @textutil: The #GailTextUtil to be initialized.
- * @text: A gchar* which points to the text to be stored in the GailTextUtil
- *
- * This function initializes the GailTextUtil with the specified character string,
- **/
-void
-gail_text_util_text_setup (GailTextUtil *textutil,
- const gchar *text)
-{
- g_return_if_fail (GAIL_IS_TEXT_UTIL (textutil));
-
- if (textutil->buffer)
- {
- if (!text)
- {
- g_object_unref (textutil->buffer);
- textutil->buffer = NULL;
- return;
- }
- }
- else
- {
- textutil->buffer = gtk_text_buffer_new (NULL);
- }
-
- gtk_text_buffer_set_text (textutil->buffer, text, -1);
-}
-
-/**
- * gail_text_util_buffer_setup:
- * @textutil: A #GailTextUtil to be initialized
- * @buffer: The #GtkTextBuffer which identifies the text to be stored in the GailUtil.
- *
- * This function initializes the GailTextUtil with the specified GtkTextBuffer
- **/
-void
-gail_text_util_buffer_setup (GailTextUtil *textutil,
- GtkTextBuffer *buffer)
-{
- g_return_if_fail (GAIL_IS_TEXT_UTIL (textutil));
-
- textutil->buffer = g_object_ref (buffer);
-}
-
-/**
- * gail_text_util_get_text:
- * @textutil: A #GailTextUtil
- * @layout: A gpointer which is a PangoLayout, a GtkTreeView of NULL
- * @function: An enumeration specifying whether to return the text before, at, or
- * after the offset.
- * @boundary_type: The boundary type.
- * @offset: The offset of the text in the GailTextUtil
- * @start_offset: Address of location in which the start offset is returned
- * @end_offset: Address of location in which the end offset is returned
- *
- * This function gets the requested substring from the text in the GtkTextUtil.
- * The layout is used only for getting the text on a line. The value is NULL
- * for a GtkTextView which is not wrapped, is a GtkTextView for a GtkTextView
- * which is wrapped and is a PangoLayout otherwise.
- *
- * Returns: the substring requested
- **/
-gchar*
-gail_text_util_get_text (GailTextUtil *textutil,
- gpointer layout,
- GailOffsetType function,
- AtkTextBoundary boundary_type,
- gint offset,
- gint *start_offset,
- gint *end_offset)
-{
- GtkTextIter start, end;
- gint line_number;
- GtkTextBuffer *buffer;
-
- g_return_val_if_fail (GAIL_IS_TEXT_UTIL (textutil), NULL);
-
- buffer = textutil->buffer;
- if (buffer == NULL)
- {
- *start_offset = 0;
- *end_offset = 0;
- return NULL;
- }
-
- if (!gtk_text_buffer_get_char_count (buffer))
- {
- *start_offset = 0;
- *end_offset = 0;
- return g_strdup ("");
- }
- gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
-
-
- end = start;
-
- switch (function)
- {
- case GAIL_BEFORE_OFFSET:
- switch (boundary_type)
- {
- case ATK_TEXT_BOUNDARY_CHAR:
- gtk_text_iter_backward_char(&start);
- break;
- case ATK_TEXT_BOUNDARY_WORD_START:
- if (!gtk_text_iter_starts_word (&start))
- gtk_text_iter_backward_word_start (&start);
- end = start;
- gtk_text_iter_backward_word_start(&start);
- break;
- case ATK_TEXT_BOUNDARY_WORD_END:
- if (gtk_text_iter_inside_word (&start) &&
- !gtk_text_iter_starts_word (&start))
- gtk_text_iter_backward_word_start (&start);
- while (!gtk_text_iter_ends_word (&start))
- {
- if (!gtk_text_iter_backward_char (&start))
- break;
- }
- end = start;
- gtk_text_iter_backward_word_start(&start);
- while (!gtk_text_iter_ends_word (&start))
- {
- if (!gtk_text_iter_backward_char (&start))
- break;
- }
- break;
- case ATK_TEXT_BOUNDARY_SENTENCE_START:
- if (!gtk_text_iter_starts_sentence (&start))
- gtk_text_iter_backward_sentence_start (&start);
- end = start;
- gtk_text_iter_backward_sentence_start (&start);
- break;
- case ATK_TEXT_BOUNDARY_SENTENCE_END:
- if (gtk_text_iter_inside_sentence (&start) &&
- !gtk_text_iter_starts_sentence (&start))
- gtk_text_iter_backward_sentence_start (&start);
- while (!gtk_text_iter_ends_sentence (&start))
- {
- if (!gtk_text_iter_backward_char (&start))
- break;
- }
- end = start;
- gtk_text_iter_backward_sentence_start (&start);
- while (!gtk_text_iter_ends_sentence (&start))
- {
- if (!gtk_text_iter_backward_char (&start))
- break;
- }
- break;
- case ATK_TEXT_BOUNDARY_LINE_START:
- if (layout == NULL)
- {
- line_number = gtk_text_iter_get_line (&start);
- if (line_number == 0)
- {
- gtk_text_buffer_get_iter_at_offset (buffer,
- &start, 0);
- }
- else
- {
- gtk_text_iter_backward_line (&start);
- gtk_text_iter_forward_line (&start);
- }
- end = start;
- gtk_text_iter_backward_line (&start);
- }
- else if GTK_IS_TEXT_VIEW (layout)
- {
- GtkTextView *view = GTK_TEXT_VIEW (layout);
-
- gtk_text_view_backward_display_line_start (view, &start);
- end = start;
- gtk_text_view_backward_display_line (view, &start);
- }
- else if (PANGO_IS_LAYOUT (layout))
- get_pango_text_offsets (PANGO_LAYOUT (layout),
- buffer,
- function,
- boundary_type,
- offset,
- start_offset,
- end_offset,
- &start,
- &end);
- break;
- case ATK_TEXT_BOUNDARY_LINE_END:
- if (layout == NULL)
- {
- line_number = gtk_text_iter_get_line (&start);
- if (line_number == 0)
- {
- gtk_text_buffer_get_iter_at_offset (buffer,
- &start, 0);
- end = start;
- }
- else
- {
- gtk_text_iter_backward_line (&start);
- end = start;
- while (!gtk_text_iter_ends_line (&start))
- {
- if (!gtk_text_iter_backward_char (&start))
- break;
- }
- gtk_text_iter_forward_to_line_end (&end);
- }
- }
- else if GTK_IS_TEXT_VIEW (layout)
- {
- GtkTextView *view = GTK_TEXT_VIEW (layout);
-
- gtk_text_view_backward_display_line_start (view, &start);
- if (!gtk_text_iter_is_start (&start))
- {
- gtk_text_view_backward_display_line (view, &start);
- end = start;
- if (!gtk_text_iter_is_start (&start))
- {
- gtk_text_view_backward_display_line (view, &start);
- gtk_text_view_forward_display_line_end (view, &start);
- }
- gtk_text_view_forward_display_line_end (view, &end);
- }
- else
- {
- end = start;
- }
- }
- else if (PANGO_IS_LAYOUT (layout))
- get_pango_text_offsets (PANGO_LAYOUT (layout),
- buffer,
- function,
- boundary_type,
- offset,
- start_offset,
- end_offset,
- &start,
- &end);
- break;
- }
- break;
-
- case GAIL_AT_OFFSET:
- switch (boundary_type)
- {
- case ATK_TEXT_BOUNDARY_CHAR:
- gtk_text_iter_forward_char (&end);
- break;
- case ATK_TEXT_BOUNDARY_WORD_START:
- if (!gtk_text_iter_starts_word (&start))
- gtk_text_iter_backward_word_start (&start);
- if (gtk_text_iter_inside_word (&end))
- gtk_text_iter_forward_word_end (&end);
- while (!gtk_text_iter_starts_word (&end))
- {
- if (!gtk_text_iter_forward_char (&end))
- break;
- }
- break;
- case ATK_TEXT_BOUNDARY_WORD_END:
- if (gtk_text_iter_inside_word (&start) &&
- !gtk_text_iter_starts_word (&start))
- gtk_text_iter_backward_word_start (&start);
- while (!gtk_text_iter_ends_word (&start))
- {
- if (!gtk_text_iter_backward_char (&start))
- break;
- }
- gtk_text_iter_forward_word_end (&end);
- break;
- case ATK_TEXT_BOUNDARY_SENTENCE_START:
- if (!gtk_text_iter_starts_sentence (&start))
- gtk_text_iter_backward_sentence_start (&start);
- if (gtk_text_iter_inside_sentence (&end))
- gtk_text_iter_forward_sentence_end (&end);
- while (!gtk_text_iter_starts_sentence (&end))
- {
- if (!gtk_text_iter_forward_char (&end))
- break;
- }
- break;
- case ATK_TEXT_BOUNDARY_SENTENCE_END:
- if (gtk_text_iter_inside_sentence (&start) &&
- !gtk_text_iter_starts_sentence (&start))
- gtk_text_iter_backward_sentence_start (&start);
- while (!gtk_text_iter_ends_sentence (&start))
- {
- if (!gtk_text_iter_backward_char (&start))
- break;
- }
- gtk_text_iter_forward_sentence_end (&end);
- break;
- case ATK_TEXT_BOUNDARY_LINE_START:
- if (layout == NULL)
- {
- line_number = gtk_text_iter_get_line (&start);
- if (line_number == 0)
- {
- gtk_text_buffer_get_iter_at_offset (buffer,
- &start, 0);
- }
- else
- {
- gtk_text_iter_backward_line (&start);
- gtk_text_iter_forward_line (&start);
- }
- gtk_text_iter_forward_line (&end);
- }
- else if GTK_IS_TEXT_VIEW (layout)
- {
- GtkTextView *view = GTK_TEXT_VIEW (layout);
-
- gtk_text_view_backward_display_line_start (view, &start);
- /*
- * The call to gtk_text_iter_forward_to_end() is needed
- * because of bug 81960
- */
- if (!gtk_text_view_forward_display_line (view, &end))
- gtk_text_iter_forward_to_end (&end);
- }
- else if PANGO_IS_LAYOUT (layout)
- get_pango_text_offsets (PANGO_LAYOUT (layout),
- buffer,
- function,
- boundary_type,
- offset,
- start_offset,
- end_offset,
- &start,
- &end);
-
- break;
- case ATK_TEXT_BOUNDARY_LINE_END:
- if (layout == NULL)
- {
- line_number = gtk_text_iter_get_line (&start);
- if (line_number == 0)
- {
- gtk_text_buffer_get_iter_at_offset (buffer,
- &start, 0);
- }
- else
- {
- gtk_text_iter_backward_line (&start);
- gtk_text_iter_forward_line (&start);
- }
- while (!gtk_text_iter_ends_line (&start))
- {
- if (!gtk_text_iter_backward_char (&start))
- break;
- }
- gtk_text_iter_forward_to_line_end (&end);
- }
- else if GTK_IS_TEXT_VIEW (layout)
- {
- GtkTextView *view = GTK_TEXT_VIEW (layout);
-
- gtk_text_view_backward_display_line_start (view, &start);
- if (!gtk_text_iter_is_start (&start))
- {
- gtk_text_view_backward_display_line (view, &start);
- gtk_text_view_forward_display_line_end (view, &start);
- }
- gtk_text_view_forward_display_line_end (view, &end);
- }
- else if PANGO_IS_LAYOUT (layout)
- get_pango_text_offsets (PANGO_LAYOUT (layout),
- buffer,
- function,
- boundary_type,
- offset,
- start_offset,
- end_offset,
- &start,
- &end);
- break;
- }
- break;
-
- case GAIL_AFTER_OFFSET:
- switch (boundary_type)
- {
- case ATK_TEXT_BOUNDARY_CHAR:
- gtk_text_iter_forward_char(&start);
- gtk_text_iter_forward_chars(&end, 2);
- break;
- case ATK_TEXT_BOUNDARY_WORD_START:
- if (gtk_text_iter_inside_word (&end))
- gtk_text_iter_forward_word_end (&end);
- while (!gtk_text_iter_starts_word (&end))
- {
- if (!gtk_text_iter_forward_char (&end))
- break;
- }
- start = end;
- if (!gtk_text_iter_is_end (&end))
- {
- gtk_text_iter_forward_word_end (&end);
- while (!gtk_text_iter_starts_word (&end))
- {
- if (!gtk_text_iter_forward_char (&end))
- break;
- }
- }
- break;
- case ATK_TEXT_BOUNDARY_WORD_END:
- gtk_text_iter_forward_word_end (&end);
- start = end;
- if (!gtk_text_iter_is_end (&end))
- gtk_text_iter_forward_word_end (&end);
- break;
- case ATK_TEXT_BOUNDARY_SENTENCE_START:
- if (gtk_text_iter_inside_sentence (&end))
- gtk_text_iter_forward_sentence_end (&end);
- while (!gtk_text_iter_starts_sentence (&end))
- {
- if (!gtk_text_iter_forward_char (&end))
- break;
- }
- start = end;
- if (!gtk_text_iter_is_end (&end))
- {
- gtk_text_iter_forward_sentence_end (&end);
- while (!gtk_text_iter_starts_sentence (&end))
- {
- if (!gtk_text_iter_forward_char (&end))
- break;
- }
- }
- break;
- case ATK_TEXT_BOUNDARY_SENTENCE_END:
- gtk_text_iter_forward_sentence_end (&end);
- start = end;
- if (!gtk_text_iter_is_end (&end))
- gtk_text_iter_forward_sentence_end (&end);
- break;
- case ATK_TEXT_BOUNDARY_LINE_START:
- if (layout == NULL)
- {
- gtk_text_iter_forward_line (&end);
- start = end;
- gtk_text_iter_forward_line (&end);
- }
- else if GTK_IS_TEXT_VIEW (layout)
- {
- GtkTextView *view = GTK_TEXT_VIEW (layout);
-
- gtk_text_view_forward_display_line (view, &end);
- start = end;
- gtk_text_view_forward_display_line (view, &end);
- }
- else if (PANGO_IS_LAYOUT (layout))
- get_pango_text_offsets (PANGO_LAYOUT (layout),
- buffer,
- function,
- boundary_type,
- offset,
- start_offset,
- end_offset,
- &start,
- &end);
- break;
- case ATK_TEXT_BOUNDARY_LINE_END:
- if (layout == NULL)
- {
- gtk_text_iter_forward_line (&start);
- end = start;
- if (!gtk_text_iter_is_end (&start))
- {
- while (!gtk_text_iter_ends_line (&start))
- {
- if (!gtk_text_iter_backward_char (&start))
- break;
- }
- gtk_text_iter_forward_to_line_end (&end);
- }
- }
- else if GTK_IS_TEXT_VIEW (layout)
- {
- GtkTextView *view = GTK_TEXT_VIEW (layout);
-
- gtk_text_view_forward_display_line_end (view, &end);
- start = end;
- gtk_text_view_forward_display_line (view, &end);
- gtk_text_view_forward_display_line_end (view, &end);
- }
- else if (PANGO_IS_LAYOUT (layout))
- get_pango_text_offsets (PANGO_LAYOUT (layout),
- buffer,
- function,
- boundary_type,
- offset,
- start_offset,
- end_offset,
- &start,
- &end);
- break;
- }
- break;
- }
- *start_offset = gtk_text_iter_get_offset (&start);
- *end_offset = gtk_text_iter_get_offset (&end);
-
- return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
-}
-
-/**
- * gail_text_util_get_substring:
- * @textutil: A #GailTextUtil
- * @start_pos: The start position of the substring
- * @end_pos: The end position of the substring.
- *
- * Gets the substring indicated by @start_pos and @end_pos
- *
- * Returns: the substring indicated by @start_pos and @end_pos
- **/
-gchar*
-gail_text_util_get_substring (GailTextUtil *textutil,
- gint start_pos,
- gint end_pos)
-{
- GtkTextIter start, end;
- GtkTextBuffer *buffer;
-
- g_return_val_if_fail(GAIL_IS_TEXT_UTIL (textutil), NULL);
-
- buffer = textutil->buffer;
- if (buffer == NULL)
- return NULL;
-
- gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
- if (end_pos < 0)
- gtk_text_buffer_get_end_iter (buffer, &end);
- else
- gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
-
- return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
-}
-
-static void
-get_pango_text_offsets (PangoLayout *layout,
- GtkTextBuffer *buffer,
- GailOffsetType function,
- AtkTextBoundary boundary_type,
- gint offset,
- gint *start_offset,
- gint *end_offset,
- GtkTextIter *start_iter,
- GtkTextIter *end_iter)
-{
- PangoLayoutIter *iter;
- PangoLayoutLine *line, *prev_line = NULL, *prev_prev_line = NULL;
- gint index, start_index, end_index;
- const gchar *text;
- gboolean found = FALSE;
-
- text = pango_layout_get_text (layout);
- index = g_utf8_offset_to_pointer (text, offset) - text;
- iter = pango_layout_get_iter (layout);
- do
- {
- line = pango_layout_iter_get_line (iter);
- start_index = line->start_index;
- end_index = start_index + line->length;
-
- if (index >= start_index && index <= end_index)
- {
- /*
- * Found line for offset
- */
- switch (function)
- {
- case GAIL_BEFORE_OFFSET:
- /*
- * We want the previous line
- */
- if (prev_line)
- {
- switch (boundary_type)
- {
- case ATK_TEXT_BOUNDARY_LINE_START:
- end_index = start_index;
- start_index = prev_line->start_index;
- break;
- case ATK_TEXT_BOUNDARY_LINE_END:
- if (prev_prev_line)
- start_index = prev_prev_line->start_index +
- prev_prev_line->length;
- end_index = prev_line->start_index + prev_line->length;
- break;
- default:
- g_assert_not_reached();
- }
- }
- else
- start_index = end_index = 0;
- break;
- case GAIL_AT_OFFSET:
- switch (boundary_type)
- {
- case ATK_TEXT_BOUNDARY_LINE_START:
- if (pango_layout_iter_next_line (iter))
- end_index = pango_layout_iter_get_line (iter)->start_index;
- break;
- case ATK_TEXT_BOUNDARY_LINE_END:
- if (prev_line)
- start_index = prev_line->start_index +
- prev_line->length;
- break;
- default:
- g_assert_not_reached();
- }
- break;
- case GAIL_AFTER_OFFSET:
- /*
- * We want the next line
- */
- if (pango_layout_iter_next_line (iter))
- {
- line = pango_layout_iter_get_line (iter);
- switch (boundary_type)
- {
- case ATK_TEXT_BOUNDARY_LINE_START:
- start_index = line->start_index;
- if (pango_layout_iter_next_line (iter))
- end_index = pango_layout_iter_get_line (iter)->start_index;
- else
- end_index = start_index + line->length;
- break;
- case ATK_TEXT_BOUNDARY_LINE_END:
- start_index = end_index;
- end_index = line->start_index + line->length;
- break;
- default:
- g_assert_not_reached();
- }
- }
- else
- start_index = end_index;
- break;
- }
- found = TRUE;
- break;
- }
- prev_prev_line = prev_line;
- prev_line = line;
- }
- while (pango_layout_iter_next_line (iter));
-
- if (!found)
- {
- start_index = prev_line->start_index + prev_line->length;
- end_index = start_index;
- }
- pango_layout_iter_free (iter);
- *start_offset = g_utf8_pointer_to_offset (text, text + start_index);
- *end_offset = g_utf8_pointer_to_offset (text, text + end_index);
-
- gtk_text_buffer_get_iter_at_offset (buffer, start_iter, *start_offset);
- gtk_text_buffer_get_iter_at_offset (buffer, end_iter, *end_offset);
-}
+++ /dev/null
-/* GAIL - The GNOME Accessibility Implementation Library
- * Copyright 2001 Sun Microsystems Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GAIL_TEXT_UTIL_H__
-#define __GAIL_TEXT_UTIL_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define GAIL_TYPE_TEXT_UTIL (gail_text_util_get_type ())
-#define GAIL_TEXT_UTIL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_TEXT_UTIL, GailTextUtil))
-#define GAIL_TEXT_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_TEXT_UTIL, GailTextUtilClass))
-#define GAIL_IS_TEXT_UTIL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_TEXT_UTIL))
-#define GAIL_IS_TEXT_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_TEXT_UTIL))
-#define GAIL_TEXT_UTIL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_TEXT_UTIL, GailTextUtilClass))
-
-/**
- *GailOffsetType:
- *@GAIL_BEFORE_OFFSET: Text before offset is required.
- *@GAIL_AT_OFFSET: Text at offset is required,
- *@GAIL_AFTER_OFFSET: Text after offset is required.
- *
- * Specifies which of the functions atk_text_get_text_before_offset(),
- * atk_text_get_text_at_offset(), atk_text_get_text_after_offset() the
- * function gail_text_util_get_text() is being called for.
- **/
-typedef enum
-{
- GAIL_BEFORE_OFFSET,
- GAIL_AT_OFFSET,
- GAIL_AFTER_OFFSET
-}GailOffsetType;
-
-typedef struct _GailTextUtil GailTextUtil;
-typedef struct _GailTextUtilClass GailTextUtilClass;
-
-struct _GailTextUtil
-{
- GObject parent;
-
- GtkTextBuffer *buffer;
-};
-
-struct _GailTextUtilClass
-{
- GObjectClass parent_class;
-};
-
-GType gail_text_util_get_type (void);
-GailTextUtil* gail_text_util_new (void);
-
-void gail_text_util_text_setup (GailTextUtil *textutil,
- const gchar *text);
-void gail_text_util_buffer_setup (GailTextUtil *textutil,
- GtkTextBuffer *buffer);
-gchar* gail_text_util_get_text (GailTextUtil *textutil,
- gpointer layout,
- GailOffsetType function,
- AtkTextBoundary boundary_type,
- gint offset,
- gint *start_offset,
- gint *end_offset);
-gchar* gail_text_util_get_substring (GailTextUtil *textutil,
- gint start_pos,
- gint end_pos);
-
-G_END_DECLS
-
-#endif /*__GAIL_TEXT_UTIL_H__ */
+++ /dev/null
-EXPORTS
- gail_misc_add_attribute
- gail_misc_buffer_get_run_attributes
- gail_misc_get_default_attributes
- gail_misc_get_extents_from_pango_rectangle
- gail_misc_get_index_at_point_in_layout
- gail_misc_get_origins
- gail_misc_layout_get_run_attributes
- gail_text_util_buffer_setup
- gail_text_util_get_substring
- gail_text_util_get_text
- gail_text_util_get_type
- gail_text_util_new
- gail_text_util_text_setup
+++ /dev/null
-## Makefile.am for gtk+/tests
-include $(top_srcdir)/Makefile.decl
-
-if PLATFORM_WIN32
-no_undefined = -no-undefined
-endif
-
-moduledir = $(libdir)/gtk-3.0/modules
-
-if !OS_WIN32
-module_LTLIBRARIES = \
- libferret.la
-endif
-
-noinst_LTLIBRARIES = \
- libtestaction.la \
- libtestbutton.la \
- libtestcombo.la \
- libtestcomponent.la \
- libtestimage.la \
- libtestnotebook.la \
- libtestobject.la \
- libtestmenuitem.la \
- libtestpaned.la \
- libtestprops.la \
- libtestselection.la \
- libteststatusbar.la \
- libtesttable.la \
- libtesttext.la \
- libtesttoplevel.la \
- libtesttreetable.la \
- libtestvalues.la
-
-AM_CPPFLAGS = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/gdk \
- -I$(top_builddir)/gdk \
- -I$(top_srcdir)/gtk \
- -I$(top_builddir)/gtk \
- -DGDK_DISABLE_DEPRECATED\
- -DGTK_DISABLE_DEPRECATED
-
-AM_CFLAGS = \
- $(GTK_DEP_CFLAGS) \
- $(GTK_DEBUG_FLAGS)
-
-if !OS_WIN32
-libferret_la_SOURCES = \
- testlib.c \
- testlib.h \
- ferret.c
-
-libferret_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version \
- $(no_undefined) \
- $(LDFLAGS)
-
-libferret_la_LIBADD = \
- $(top_builddir)/gtk/libgtk-3.la \
- $(GTK_DEP_LIBS) \
- $(GAIL_INET_LIBS)
-endif
-
-libtestaction_la_SOURCES = \
- testaction.c
-
-libtestaction_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestbutton_la_SOURCES = \
- testlib.c \
- testlib.h \
- testbutton.c
-
-libtestbutton_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestcombo_la_SOURCES = \
- testlib.c \
- testlib.h \
- testcombo.c
-
-libtestcombo_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestcomponent_la_SOURCES = \
- testcomponent.c
-
-libtestcomponent_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestimage_la_SOURCES = \
- testimage.c
-
-libtestimage_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestmenuitem_la_SOURCES = \
- testlib.c \
- testlib.h \
- testmenuitem.c
-
-libtestmenuitem_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestnotebook_la_SOURCES = \
- testlib.c \
- testlib.h \
- testnotebook.c
-
-libtestnotebook_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestobject_la_SOURCES = \
- testlib.c \
- testlib.h \
- testobject.c
-
-libtestobject_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestpaned_la_SOURCES = \
- testlib.c \
- testlib.h \
- testpaned.c
-
-libtestpaned_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestprops_la_SOURCES = \
- testlib.c \
- testlib.h \
- testprops.c
-
-libtestprops_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestselection_la_SOURCES = \
- testselection.c
-
-libtestselection_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libteststatusbar_la_SOURCES = \
- teststatusbar.c
-
-libteststatusbar_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtesttable_la_SOURCES = \
- testlib.c \
- testlib.h \
- testtextlib.c \
- testtextlib.h \
- testtable.c
-
-libtesttable_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtesttext_la_SOURCES = \
- testlib.c \
- testlib.h \
- testtextlib.c \
- testtextlib.h \
- testtext.c
-
-libtesttext_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtesttoplevel_la_SOURCES = \
- testlib.c \
- testlib.h \
- testtoplevel.c
-
-libtesttoplevel_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtesttreetable_la_SOURCES = \
- testlib.c \
- testlib.h \
- testtreetable.c
-
-libtesttreetable_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
-libtestvalues_la_SOURCES = \
- testvalues.c
-
-libtestvalues_la_LDFLAGS = \
- -rpath $(moduledir) -module -avoid-version $(no_undefined) \
- $(top_builddir)/gtk/libgtk-3.la \
- $(top_builddir)/gdk/libgdk-3.la \
- $(GTK_DEP_LIBS) \
- $(LDFLAGS)
-
--include $(top_srcdir)/git.mk
+++ /dev/null
-
-============================
-GAIL README
-Last Updated: August 2, 2001
-============================
-
-
-General Info
-============
-
-This README describes how to use the various test programs
-in the gail/tests directory.
-
-To run the various test programs described in this README,
-the test libraries must be built and installed. Running
-"make", then "make install" in the gail top-level directory
-will take care of this. Then do the following:
-
-1. Set the environment variable GTK_MODULES to
- "libgail:lib<testname>"
-
- For example, for ferret, it would be "libgail:libferret"
-
-2. Run the GTK+ test program specified. These test programs
- are found in the GTK+ build directory in the subdirectory
- called "tests".
-
-Most test programs will display output directly to the
-terminal window where the GTK+ test program was launched.
-Some test programs (testtable and testtext) will launch a
-test GUI program which allows more interactive testing.
-
-The test GUI has two windows. The first window is the
-"Test Control" window and the second window is the
-"Test Output" window. In the "Test Control" window,
-press the button(s) that corresponds to the tests to run
-and press the "Run Tests" button at the bottom of the
-screen. Some tests have associated text entry fields
-which become active when the button is toggled on. These
-text entry fields correspond to arguments that affect how
-the test is executed. They are pre-filled with default
-values but the user can change them if desired. The
-output from the tests is displayed in the "Test Output"
-window.
-
-
-testlib
-=======
-
-Contains general purpose functionality that is used by the
-various tests. These include functions that find a specific
-widget/AtkObject in the test program, and functions used by
-tests that use the Gail Test GUI.
-
-
-ferret
-======
-
-Ferret is a passive in-process test tool for ATK and GAIL.
-
-Run a GTK+-2.0 application such as "testgtk", and ferret will
-display a window on screen. In this window accessibility
-information about the GTK+ widgets will appear as they
-receive focus.
-
-The ferret window has several tabs, one for each of the
-following ATK interfaces.
-
- Object
- Action
- Component
- Image
- Table
- Text
- Value
-
-Tabs that do not apply to the current widget in focus will be
-displayed as inactive. Clicking on an active tab will display
-information about the AtkObject accessed via the ATK API. In the
-Action tab the various actions are displayed as buttons. When
-a button is clicked, the action specified on the button's
-label is performed.
-
-If you have installed the "festival" speech synthesis system,
-running festival in server mode (festival --server) and turning
-on Ferret's Festival support will cause the following to happen:
-
-1. AtkObject accessible names, roles, and keybindings will be
- spoken as they receive focus.
-2. When the caret (cursor) is moved in a text field, the
- current line will be spoken, unless the caret is moved
- just a single character. In the later case, only the
- single character after the caret will be spoken.
-
-Festival support can be turned on by checking "Festival" in the
-menu, or by setting the environment variable FERRET_FESTIVAL
-prior to starting the test. By checking "Festival Terse" or
-by setting the environment variable FERRET_TERSE, only the
-name of the AtkObject will be spoken (and not the roles and
-keybindings).
-
-A magnifier can be turned on to enlarge the widget in focus
-by checking "Magnifier" in the menu, or by setting the
-environment variable FERRET_MAGNIFIER. This requires that
-the magnifier standalone code is running.
-
-Checking "Track Mouse in the menu or by setting the environment
-variable FERRET_MOUSETRACK causes ferret to display information
-about the widget that is under the mouse rather than the widget
-that has focus. The mouse is tracked via GtkWidget
-"enter_notify_event" signals, so flyweight objects are not tracked.
-
-Checking "Terminal Output" in the menu or by setting the
-environment variable FERRET_ASCII will display the information
-that is normally displayed to the ferret GUI window to the
-terminal screen.
-
-Checking "No ATK Signals" in the menu or by setting the
-environment variable FERRET_NOSIGNALS will cause ferret to
-ignore any ATK signals, and it will not update its display
-when such signals occur.
-
-
-testaction
-==========
-
-This is a GTK+ module used to test the implementation of the ATK
-interface AtkAction, except for atk_action_do_action() in the GAIL
-library. It is normally used with the GTK+ test program testgtk.
-
-
-testbutton
-==========
-
-This is a GTK+ module used to test the accessible implementation
-for buttons. It is normally used with the GTK+ test program testgtk.
-
-Set the TEST_ACCESSIBLE_NAME environment variable to have the test
-driver attach to a widget by widget name (compared via the
-gtk_widget_get_name function call).
-
-Set the environment variable TEST_ACCESSIBLE_AUTO and the program
-will execute the action defined for a GailButton once.
-
-
-testcombo
-=========
-
-This is a GTK+ module used to test the implementation of the ATK action
-interfaces on GailCombo. It is normally used with the GTK+ test program
-testgtk by putting the focus in the GtkCombo in entry window.
-
-
-testcomponent
-=============
-
-This is a GTK+ module used to test the implementation of the ATK
-interface AtkComponent in the GAIL library. It is normally used with the
-GTK+ test program testgtk.
-
-
-testimage
-=========
-
-This is a GTK+ module used to test the implementation of the ATK
-interface AtkImage in the GAIL library. It is normally used with the GTK+
-test program testgtk, but can also be used with testdnd when you want
-to test GtkPixmap. This modules pops up an extra dialog on startup , containing
-GtkArrows and a GtkImage. This dialog has to be closed before control is returned to main window.
-
-
-testmenuitem
-============
-
-This is a GTK+ module used to test the accessible implementation
-for menu items. It is normally used with the GTK+ test program testgtk.
-
-Set the TEST_ACCESSIBLE_NAME environment variable to have the test
-driver attach to a widget by widget name (compared via the
-gtk_widget_get_name function call).
-
-Set the environment variable TEST_ACCESSIBLE_AUTO and the program
-will execute the action defined for a GailButton once.
-
-
-testnotebook
-=============
-
-This is a GTK+ module used to test the implementation of the ATK
-interface AtkSelection for GailNotebook. It is normally used with the
-GTK+ test program testgtk.
-
-
-testobject
-==========
-
-This is a GTK+ module used to test the implementation of the ATK
-interface in atkobject.h in the GAIL library. It is normally used with the
-GTK+ test program testgtk.
-
-
-testpaned
-=========
-
-This is a GTK+ module used to test the implementation of the ATK
-interface AtkValue for GailPaned. It is normally used with the
-GTK+ test program testgtk. It checks the setting of the position
-programmatically and that notification is received if the position
-is changed interactively.
-
-
-testprops
-==========
-
-This is a GTK+ module used to test the implementation of ATK properties
-and property change handlers in the GAIL library. It is normally used with
-the GTK+ test program testgtk. To see the changing of the state
-ATK_STATE_SHOWING use menus in "progress bar". To see the changing of the
-state ATK_STATE_SENSITIVE uses "labels". To see changing of child and parent
-use resize check box in "panes".
-
-Set the TEST_ACCESSIBLE_NAME environment variable to have the test
-driver attach to a widget by widget name (compared via the
-gtk_widget_get_name function call).
-
-
-testselection
-=============
-
-This is a GTK+ module used to test the implementation of the AtkSelection
-interface works for the GAIL library. It is normally used with the GTK+
-test program testgtk and clicking on the menus option. It can also be used
-with the GtkCombo which can be accessed by clicking on the entry option.
-
-
-teststatusbar
-=============
-
-This is a GTK+ module used to test that the text on the statusbar
-can be retrieved using GailStatusbar. It is normally used with the GTK+
-test program testgtk and clicking on statusbar button.
-
-
-testtable
-=========
-
-This is GTK+ module used to test the implementation of AtkTable
-interfaces. It can be used with GailTreeView, for example. It
-can be used with any of the following GTK+ test programs:
-testtreecolumns, testtreefocus, testtreesort, testtreeview,
-or treestoretest.
-
-Set the TEST_ACCESSIBLE_NO_PROPERTIES environment variable
-to not receive information about property values changing
-(like cell state changes).
-
-Set the TEST_ACCESSIBLE_NO_GUI environment variable to run the
-test without the GUI program.
-
-
-testtext
-========
-
-This is a GTK+ module used to test the implementation of AtkText and
-AtkEditableText interfaces on GailTextView. It is normally used with
-the GTK+ test program testtext started with a text file loaded.
-It can also be used with the GTK+ test program testgtk, and then
-click on the "entry" or "label" button.
-
-Set the TEST_ACCESSIBLE_NAME environment variable to have the test
-driver attach to a widget by widget name (compared via the
-gtk_widget_get_name function call).
-
-Set the TEST_ACCESSIBLE_DELAY environment variable to an integer
-and the test driver will attach to only a widget on the nth screen
-that is displayed.
-
-
-testtoplevel
-============
-
-This test exercises the AtkUtil functions. It accesses the
-atk_get_root() toplevel object, sets/removes global listeners,
-and displays the ATK implementation name/version.
-
-Set the TEST_ACCESSIBLE_DEPTH environment variable to control
-how deep the children of the toplevel object are displayed.
-The default is a depth of 2. Specifying a depth of -1 will
-show the complete hierarchy.
-
-
-testvalues
-==========
-
-This is a GTK+ module used to test the implementation of AtkValue interface
-works for the GAIL library. GailProgressbar, GailSpinbutton and GailRange
-can all be tested using this module.
-
-
-GAIL README Authors
-===================
-
--Brian Cameron (brian.cameron@sun.com)
--Bill Haneman (bill.haneman@sun.com)
--Padraig O'Briain (padraig.obriain@sun.com)
-
+++ /dev/null
-#define MAX_BUFFER 256
-#define MAX_GROUPS 20
-#define MAX_NAME_VALUE 20
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <strings.h>
-
-#include "testlib.h"
-
-typedef enum
-{
- OBJECT,
- ACTION,
- COMPONENT,
- IMAGE,
- SELECTION,
- TABLE,
- TEXT,
- VALUE,
- END_TABS
-} TabNumber;
-
-typedef enum
-{
- OBJECT_INTERFACE,
- RELATION_INTERFACE,
- STATE_INTERFACE,
- ACTION_INTERFACE,
- COMPONENT_INTERFACE,
- IMAGE_INTERFACE,
- SELECTION_INTERFACE,
- TABLE_INTERFACE,
- TEXT_INTERFACE,
- TEXT_ATTRIBUTES,
- VALUE_INTERFACE
-} GroupId;
-
-typedef enum
-{
- VALUE_STRING,
- VALUE_BOOLEAN,
- VALUE_TEXT,
- VALUE_BUTTON
-} ValueType;
-
-/* GUI Information for the group */
-
-typedef struct
-{
- GroupId group_id;
- GtkFrame *scroll_outer_frame;
- GtkWidget *frame;
- GtkBox *group_vbox;
- GtkAdjustment *adj;
- GList *name_value;
- gchar *name;
- gboolean is_scrolled;
- gint default_height;
-} GroupInfo;
-
-typedef struct
-{
- GList *groups;
- GtkWidget *page;
- GtkWidget *main_box;
- gchar *name;
-} TabInfo;
-
-typedef struct
-{
- ValueType type;
- gboolean active;
-
- GtkBox *column1, *column2, *hbox;
- GtkLabel *label;
-
- GtkButton *button;
- GValue button_gval;
- gulong signal_id;
- AtkObject *atkobj;
- gint action_num;
-
- GtkWidget *string;
- GtkWidget *boolean;
- GtkWidget *text;
-} NameValue;
-
-typedef enum {
- FERRET_SIGNAL_OBJECT,
- FERRET_SIGNAL_TEXT,
- FERRET_SIGNAL_TABLE
-} FerretSignalType;
-
-/* Function prototypes */
-
-/* GUI functions */
-
-static void _init_data(void);
-static void _create_window(void);
-static void _add_menu(GtkWidget ** menu, GtkWidget ** menuitem,
- gchar * name, gboolean init_value, GCallback func);
-static void _clear_tab(TabNumber tab_n);
-static void _greyout_tab (GtkWidget *widget, gboolean is_sensitive);
-static void _finished_group(TabNumber tab_n, gint group_num);
-static gboolean _object_is_ours (AtkObject *aobject);
-static void _create_event_watcher (void);
-
-/* Mouse Watcher/Magnifier/Festival functions */
-
-static gboolean _mouse_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-static gboolean _button_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-static void _send_to_magnifier (gint x, gint y, gint w, gint h);
-static void _send_to_festival (const gchar * name,
- const gchar * role_name, const gchar * accel);
-static void _speak_caret_event (AtkObject * aobject);
-static void _festival_say (const gchar * text);
-static void _festival_write (const gchar * text, int fd);
-static gint _festival_init (void);
-
-/* Update functions */
-
-static void _update_current_page(GtkNotebook *notebook, gpointer p,
- guint current_page);
-static void _update(TabNumber top_tab, AtkObject *aobject);
-
-/* Print functions */
-
-static void _print_accessible (AtkObject *aobject);
-
-static gint _print_object (AtkObject *aobject);
-static gint _print_relation (AtkObject *aobject);
-static gint _print_state (AtkObject *aobject);
-
-static gint _print_action (AtkAction *aobject);
-static gint _print_component (AtkComponent *aobject);
-static gint _print_image (AtkImage *aobject);
-static gint _print_selection (AtkSelection *aobject);
-static gint _print_table (AtkTable *aobject);
-static gint _print_text (AtkText *aobject);
-static gint _print_text_attributes (AtkText *aobject);
-static gint _print_value (AtkValue *aobject);
-static void _print_value_type(gint group_num, gchar *type, GValue *value);
-static gint _print_groupname(TabNumber tab_n, GroupId group_id,
- const char *groupname);
-static NameValue* _print_key_value(TabNumber tab_n, gint group_number,
- const char *label, gpointer value, ValueType type);
-static void _print_signal(AtkObject *aobject, FerretSignalType type,
- const char *name, const char *info);
-
-/* Data Access functions */
-
-static GroupInfo* _get_group(TabInfo *tab, GroupId group_id,
- const gchar *groupname);
-void _get_group_scrolled(GroupInfo *group);
-static NameValue* _get_name_value(GroupInfo *group, const gchar *label,
- gpointer value, ValueType type);
-
-/* Signal handlers */
-
-static void _update_handlers(AtkObject *obj);
-static void _notify_text_insert_handler (GObject *obj,
- int position, int offset);
-static void _notify_text_delete_handler (GObject *obj,
- int position, int offset);
-static void _notify_caret_handler (GObject *obj, int position);
-static void _notify_table_row_inserted (GObject *obj,
- gint start_offset, gint length);
-static void _notify_table_column_inserted (GObject *obj,
- gint start_offset, gint length);
-static void _notify_table_row_deleted (GObject *obj,
- gint start_offset, gint length);
-static void _notify_table_column_deleted (GObject *obj,
- gint start_offset, gint length);
-static void _notify_table_row_reordered (GObject *obj);
-static void _notify_table_column_reordered (GObject *obj);
-static void _notify_object_child_added (GObject *obj,
- gint index, AtkObject *child);
-static void _notify_object_child_removed (GObject *obj,
- gint index, AtkObject *child);
-static void _notify_object_state_change (GObject *obj,
- gchar *name, gboolean set);
-
-/* Property handlers */
-
-static void _property_change_handler (AtkObject *obj,
- AtkPropertyValues *values);
-
-/* Ferret GUI callbacks */
-
-void _action_cb(GtkWidget *widget, gpointer *userdata);
-void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data);
-void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data);
-void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data);
-void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data);
-void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data);
-void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data);
-void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data);
-
-/* Global variables */
-static GtkNotebook *notebook;
-static TabInfo *nbook_tabs[END_TABS];
-static gint mouse_watcher_focus_id = -1;
-static gint mouse_watcher_button_id = -1;
-static gint focus_tracker_id = -1;
-static gboolean use_magnifier = FALSE;
-static gboolean use_festival = FALSE;
-static gboolean track_mouse = FALSE;
-static gboolean track_focus = TRUE;
-static gboolean say_role = TRUE;
-static gboolean say_accel = TRUE;
-static gboolean display_ascii = FALSE;
-static gboolean no_signals = FALSE;
-static gint last_caret_offset = 0;
-
-static AtkObject *last_object = NULL;
-static GtkWidget *mainWindow = NULL;
-static GtkWidget *vbox1 = NULL;
-static GtkWidget *menu = NULL;
-static GtkWidget *menutop = NULL;
-static GtkWidget *menubar = NULL;
-static GtkWidget *menuitem_terminal = NULL;
-static GtkWidget *menuitem_no_signals = NULL;
-static GtkWidget *menuitem_magnifier = NULL;
-static GtkWidget *menuitem_festival = NULL;
-static GtkWidget *menuitem_festival_terse = NULL;
-static GtkWidget *menuitem_trackmouse = NULL;
-static GtkWidget *menuitem_trackfocus = NULL;
-
-#ifdef HAVE_SOCKADDR_UN_SUN_LEN
-static struct sockaddr_un mag_server = { 0, AF_UNIX , "/tmp/magnifier_socket" };
-static struct sockaddr_un client = { 0 , AF_UNIX, "/tmp/mag_client"};
-#else
-static struct sockaddr_un mag_server = { AF_UNIX , "/tmp/magnifier_socket" };
-static struct sockaddr_un client = { AF_UNIX, "/tmp/mag_client"};
-#endif
-
-/* GUI Information for the output window */
-typedef struct
-{
- GtkWindow *outputWindow;
- GtkWidget *hbox;
- GtkWidget *vbox;
- GtkWidget *label;
- GtkWidget *textInsert;
- gchar *testTitle;
-} MainDialog;
-
-static void
-_send_to_magnifier(gint x, gint y, gint w, gint h)
-{
- int desc;
- int length_msg G_GNUC_UNUSED;
- gchar buff[100];
-
- sprintf (buff, "~5:%d,%d", x+w/2, y+h/2);
-
-#ifdef MAG_DEBUG
- g_print ("sending magnifier: %s\n", buff);
-#endif
-
-#ifdef HAVE_SOCKADDR_UN_SUN_LEN
- mag_server.sun_len = SUN_LEN(&mag_server);
- client.sun_len = SUN_LEN(&client);
-#endif
-
- if((desc=socket(AF_UNIX,SOCK_STREAM,0)) == -1){
- perror("socket");
- return;
- }
- unlink("/tmp/mag_client");
-
- if (bind(desc, (struct sockaddr*)&client, sizeof(client)) == -1)
- {
- perror("bind");
- return;
- }
-
- if (connect(desc,(struct sockaddr*)&mag_server,sizeof(mag_server)) == -1)
- {
- perror("connect");
- return;
- }
-
- length_msg = write(desc,buff,strlen(buff));
- unlink("/tmp/mag_client");
- return;
-}
-
-static int _festival_init (void)
-{
- int fd;
- struct sockaddr_in name;
- int tries = 2;
-
- name.sin_family = AF_INET;
- name.sin_port = htons (1314);
- name.sin_addr.s_addr = htonl(INADDR_ANY);
- fd = socket (PF_INET, SOCK_STREAM, 0);
-
- while (connect(fd, (struct sockaddr *) &name, sizeof (name)) < 0) {
- if (!tries--) {
- perror ("connect");
- return -1;
- }
- }
-
- _festival_write ("(audio_mode'async)", fd);
- return fd;
-}
-
-static void _festival_say (const gchar *text)
-{
- static int fd = 0;
- gchar *quoted;
- gchar *p;
- gchar prefix [100];
- const gchar *stretch;
-
- fprintf (stderr, "saying %s\n", text);
-
- if (!fd)
- {
- fd = _festival_init ();
- }
-
- quoted = g_malloc(100+strlen(text)*2);
-
- stretch = g_strdup (g_getenv ("FESTIVAL_STRETCH"));
- if (!stretch) stretch = "0.75";
- sprintf (prefix, "(audio_mode'shutup)\n (Parameter.set 'Duration_Stretch %s)\n (SayText \"", stretch);
-
- strcpy(quoted, prefix);
- p = quoted + strlen (prefix);
- while (*text) {
- if ( *text == '\\' || *text == '"' )
- *p = '\\';
- *p++ = *text++;
- }
- *p++ = '"';
- *p++ = ')';
- *p = 0;
-
- _festival_write (quoted, fd);
-
- g_free(quoted);
-}
-
-
-static void _send_to_festival (const gchar *role_name,
- const gchar *name, const gchar *accel)
-{
- gchar *string;
- int len = (strlen (role_name)+1 + strlen (name)+2 + 4 + strlen (accel)+2);
- int i, j;
- gchar ch;
- gchar *accel_name;
-
- string = (gchar *) g_malloc (len * sizeof (gchar));
-
- i = 0;
- if (say_role)
- {
- j = 0;
- while (role_name[j])
- {
- ch = role_name[j++];
- if (ch == '_') ch = ' ';
- string[i++] = ch;
- };
- string[i++] = ' ';
- }
- j = 0;
- while (name[j])
- {
- ch = name[j++];
- if (ch == '_') ch = ' ';
- string[i++] = ch;
- };
- if ((say_accel) && (strlen (accel) > 0))
- {
- accel_name = (gchar *)accel;
- if (strncmp (accel, "<C", 2) == 0)
- {
- accel_name = strncpy (accel_name, " control ", 9);
- }
- else if (strncmp (accel, " control", 5))
- {
- string[i++] = ' ';
- string[i++] = 'a';
- string[i++] = 'l';
- string[i++] = 't';
- string[i++] = ' ';
- }
- j = 0;
- while (accel_name[j])
- {
- ch = accel_name[j++];
- if (ch == '_') ch = ' ';
- string[i++] = ch;
- };
- }
- string[i] = '\0';
-
- _festival_say (string);
- g_free (string);
-}
-
-static void _festival_write (const gchar *command_string, int fd)
-{
- gssize n_bytes;
-
- if (fd < 0) {
- perror("socket");
- return;
- }
- n_bytes = write(fd, command_string, strlen(command_string));
- g_assert (n_bytes == strlen(command_string));
-}
-
-static void _speak_caret_event (AtkObject *aobject)
-{
- gint dummy1, dummy2;
- gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
- gchar * text;
-
- if (abs(caret_offset - last_caret_offset) > 1)
- {
- text = atk_text_get_text_at_offset (ATK_TEXT (aobject),
- caret_offset,
- ATK_TEXT_BOUNDARY_LINE_START,
- &dummy1,
- &dummy2);
- }
- else
- {
- text = atk_text_get_text_before_offset (ATK_TEXT (aobject),
- caret_offset,
- ATK_TEXT_BOUNDARY_CHAR,
- &dummy1,
- &dummy2);
- }
- _festival_say (text);
- g_free (text);
- last_caret_offset = caret_offset;
-}
-
-static void
-_greyout_tab (GtkWidget *page_child, gboolean is_sensitive)
-{
- GtkWidget *tab;
-
- tab = gtk_notebook_get_tab_label (notebook, page_child);
- if (tab)
- gtk_widget_set_sensitive (GTK_WIDGET (tab), is_sensitive);
-}
-
-static void
-_refresh_notebook (AtkObject *aobject)
-{
- if (ATK_IS_OBJECT (aobject))
- {
- _greyout_tab (nbook_tabs[ACTION]->page, ATK_IS_ACTION(aobject));
- _greyout_tab (nbook_tabs[COMPONENT]->page, ATK_IS_COMPONENT(aobject));
- _greyout_tab (nbook_tabs[IMAGE]->page, ATK_IS_IMAGE(aobject));
- _greyout_tab (nbook_tabs[SELECTION]->page, ATK_IS_SELECTION(aobject));
- _greyout_tab (nbook_tabs[TABLE]->page, ATK_IS_TABLE(aobject));
- _greyout_tab (nbook_tabs[TEXT]->page, ATK_IS_TEXT(aobject));
- _greyout_tab (nbook_tabs[VALUE]->page, ATK_IS_VALUE(aobject));
- }
-}
-
-static void _print_accessible (AtkObject *aobject)
-{
- TabNumber top_tab;
-
- if (_object_is_ours(aobject))
- {
- if (display_ascii)
- g_print("\nFocus entered the ferret output window!\n");
- return;
- }
-
- _refresh_notebook(aobject);
-
- if (display_ascii)
- g_print("\nFocus change\n");
-
- /* Do not attach signal handlers if the user has asked not to */
- if (!no_signals)
- _update_handlers(aobject);
- else
- last_object = aobject; /* _update_handler normally does this */
-
- top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
- _update(top_tab, aobject);
-
- if (use_magnifier)
- {
- gint x, y;
- gint w=0, h=0;
-
- if (ATK_IS_TEXT (aobject))
- {
- gint x0, y0, w0, h0;
- gint xN, yN, wN, hN;
- gint len;
- len = atk_text_get_character_count (ATK_TEXT (aobject));
- atk_text_get_character_extents (ATK_TEXT (aobject), 0,
- &x0, &y0, &w0, &h0,
- ATK_XY_SCREEN);
- if (len > 0)
- {
- atk_text_get_character_extents (ATK_TEXT (aobject), len-1,
- &xN, &yN, &wN, &hN,
- ATK_XY_SCREEN);
- x = MIN (x0, xN);
- y = MIN (y0, yN);
- w = MAX (x0+w0, xN+wN) - x;
- h = MAX (y0+h0, yN+hN) - y;
- }
- else
- {
- x = x0;
- y = y0;
- }
- }
- else if (ATK_IS_COMPONENT (aobject))
- {
- atk_component_get_extents (ATK_COMPONENT(aobject),
- &x, &y, &w, &h,
- ATK_XY_SCREEN);
- }
- if (w > -1) _send_to_magnifier (x, y, w, h);
- }
-}
-
-static gboolean
-_object_is_ours (AtkObject *aobject)
-{
- /* determine whether this object is parented by our own accessible... */
-
- AtkObject *toplevel = aobject;
-
- while (atk_object_get_role(aobject) != ATK_ROLE_FRAME)
- {
- aobject = atk_object_get_parent (aobject);
- if (aobject == NULL) break;
- toplevel = aobject;
- };
-
- /*
- * Some widgets do not have an ATK_ROLE_FRAME at the top,
- * so ignore those.
- */
- if (aobject != NULL)
- {
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (toplevel));
- if (widget == mainWindow)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gchar *
-ferret_get_name_from_container (AtkObject *aobject)
-{
- gchar *s = NULL;
- gint n = atk_object_get_n_accessible_children (aobject);
- gint i = 0;
-
- while (!s && (i < n))
- {
- AtkObject *child;
- child = atk_object_ref_accessible_child (aobject, i);
- if (ATK_IS_TEXT (child))
- {
- gint count = atk_text_get_character_count (ATK_TEXT (child));
- s = atk_text_get_text (ATK_TEXT (child),
- 0,
- count);
- }
- g_object_unref (child);
- ++i;
- }
-
- if (!s)
- {
- s = g_strdup ("");
- }
- return s;
-}
-
-static gint
-_print_object (AtkObject *aobject)
-{
- GtkWidget *widget;
- const gchar * parent_name = NULL;
- const gchar * name = NULL;
- const gchar * description = NULL;
- const gchar * typename = NULL;
- const gchar * parent_typename = NULL;
- const gchar * role_name = NULL;
- const gchar * accel_name = NULL;
- const gchar * text = NULL;
- AtkRole role;
- AtkObject *parent = NULL;
- static AtkObject *prev_aobject = NULL;
- gint n_children = 0;
- gint index_in_parent = -1;
- gchar *output_str;
- gint group_num;
- TabNumber tab_n = OBJECT;
-
- group_num = _print_groupname(tab_n, OBJECT_INTERFACE, "Object Interface");
-
- name = atk_object_get_name (aobject);
- typename = g_type_name (G_OBJECT_TYPE (aobject));
- description = atk_object_get_description (aobject);
- parent = atk_object_get_parent(aobject);
- if (parent)
- index_in_parent = atk_object_get_index_in_parent(aobject);
- n_children = atk_object_get_n_accessible_children(aobject);
- role = atk_object_get_role(aobject);
- role_name = atk_role_get_name(role);
-
- if (ATK_IS_ACTION (aobject))
- {
- accel_name = atk_action_get_keybinding (ATK_ACTION(aobject), 0);
- if (!accel_name) accel_name = "";
- }
- else
- {
- accel_name = "";
- }
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (aobject));
- if (widget)
- {
- _print_key_value(tab_n, group_num, "Widget name",
- (gpointer)gtk_widget_get_name (widget),
- VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Widget name", "No Widget",
- VALUE_STRING);
- }
-
- if (typename)
- {
- _print_key_value(tab_n, group_num, "Accessible Type",
- (gpointer)typename, VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Accessible Type", "NULL",
- VALUE_STRING);
- }
-
- if (name)
- {
- _print_key_value(tab_n, group_num, "Accessible Name",
- (gpointer)name, VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Accessible Name", "(unknown)",
- VALUE_STRING);
- }
- if (use_festival)
- {
- if (aobject != prev_aobject)
- {
- if (ATK_IS_TEXT (aobject) && !name)
- {
- text =
- atk_text_get_text_at_offset (ATK_TEXT (aobject),
- (gint) 0,
- ATK_TEXT_BOUNDARY_SENTENCE_END,
- (gint *) NULL,
- (gint *) NULL);
- fprintf (stderr, "first sentence: %s\n", text);
- _send_to_festival (role_name,
- text, "");
- if (!name) name = "no name";
- }
- else
- {
- text = "";
- if (!name)
- {
- if (atk_object_get_role (aobject) == ATK_ROLE_TABLE_CELL)
- {
- gchar *cname = ferret_get_name_from_container (aobject);
- if (cname) name = g_strdup (cname);
- }
- else if (atk_object_get_role (aobject) == ATK_ROLE_CHECK_BOX)
- {
- name = g_strdup ("check box");
- }
- else
- {
- name = "no name";
- }
- }
- _send_to_festival (role_name, name, accel_name);
- }
- }
- }
-
- if (parent)
- {
- parent_name = atk_object_get_name(parent);
-
- parent_typename = g_type_name (G_OBJECT_TYPE (parent));
-
- if (parent_typename)
- {
- _print_key_value(tab_n, group_num, "Parent Accessible Type",
- (gpointer)parent_typename, VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num,
- "Parent Accessible Type", "NULL", VALUE_STRING);
- }
-
- if (parent_name)
- {
- _print_key_value(tab_n, group_num, "Parent Accessible Name",
- (gpointer)parent_name, VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num,
- "Parent Accessible Name", "NULL", VALUE_STRING);
- }
-
- output_str = g_strdup_printf("%d", index_in_parent);
- _print_key_value(tab_n, group_num, "Index in Parent",
- (gpointer)output_str, VALUE_STRING);
- g_free(output_str);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Parent", "NULL", VALUE_STRING);
- }
-
- if (description)
- {
- _print_key_value(tab_n, group_num, "Accessible Description",
- (gpointer)description, VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num,
- "Accessible Description", "NULL", VALUE_STRING);
- }
-
- if (role_name)
- {
- _print_key_value(tab_n, group_num, "Accessible Role", (gpointer)role_name,
- VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Accessible Role", "NULL",
- VALUE_STRING);
- }
-
- output_str = g_strdup_printf("%d", n_children);
- _print_key_value(tab_n, group_num, "Number Children", (gpointer)output_str,
- VALUE_STRING);
- g_free(output_str);
- prev_aobject = aobject;
-
- return(group_num);
-}
-
-static gint
-_print_relation (AtkObject *aobject)
-{
- AtkRelationSet* relation_set = atk_object_ref_relation_set (aobject);
- gint n_relations = atk_relation_set_get_n_relations (relation_set);
- gint group_num;
- TabNumber tab_n = OBJECT;
-
- group_num = _print_groupname(tab_n, RELATION_INTERFACE,
- "Relation Interface");
-
- if (relation_set)
- {
- AtkRelation * relation;
- const gchar * relation_name = NULL;
- const gchar * relation_obj_name = NULL;
- AtkRelationType relation_type;
- AtkObject *relation_obj;
- GPtrArray * relation_arry;
- gchar *label_str;
- gchar *output_str;
- gint i, j;
-
- output_str = g_strdup_printf("%d", n_relations);
- _print_key_value(tab_n, group_num,
- "Number of Relations", (gpointer)output_str, VALUE_STRING);
- g_free(output_str);
-
- for (i = 0; i < n_relations; i++)
- {
- relation = atk_relation_set_get_relation (relation_set, i);
-
- relation_type = atk_relation_get_relation_type (relation);
- relation_name = atk_relation_type_get_name (relation_type);
-
- relation_arry = atk_relation_get_target(relation);
-
- if (relation_name)
- {
- label_str = g_strdup_printf("Relation %d Name", i + 1);
- _print_key_value(tab_n, group_num, label_str,
- (gpointer)relation_name, VALUE_STRING);
- g_free(label_str);
- }
- else
- {
- label_str = g_strdup_printf("Relation %d Type", i + 1);
- output_str = g_strdup_printf("%d", relation_type);
- _print_key_value(tab_n, group_num, label_str,
- (gpointer)output_str, VALUE_STRING);
- g_free(label_str);
- g_free(output_str);
- }
-
- label_str = g_strdup_printf("Relation %d with", i + 1);
- output_str = g_strdup_printf("%d AtkObjects", relation_arry->len);
- _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
- VALUE_STRING);
- g_free(label_str);
- g_free(output_str);
-
- for (j=0; j < relation_arry->len; j++)
- {
- label_str = g_strdup_printf(
- "Relation %d,%d with AtkObject Name", i + 1, j + 1);
- relation_obj = (AtkObject *)
- g_ptr_array_index(relation_arry, j);
- relation_obj_name = atk_object_get_name(relation_obj);
-
- _print_key_value(tab_n, group_num, label_str,
- (gpointer)relation_obj_name, VALUE_STRING);
- g_free(label_str);
- }
- }
-
- g_object_unref (relation_set);
- }
- return(group_num);
-}
-
-static gint
-_print_state (AtkObject *aobject)
-{
- AtkStateSet *state_set = atk_object_ref_state_set(aobject);
- gint group_num;
- TabNumber tab_n = OBJECT;
- static AtkStateType states_to_track[] =
- {
- ATK_STATE_ACTIVE,
- ATK_STATE_CHECKED,
- ATK_STATE_EXPANDED,
- ATK_STATE_EXPANDABLE,
- ATK_STATE_SELECTED,
- ATK_STATE_SHOWING,
- ATK_STATE_VISIBLE
- };
-
- group_num = _print_groupname(tab_n, STATE_INTERFACE,
- "State Interface");
-
- if (state_set)
- {
- gboolean boolean_value;
- AtkStateType one_state;
- const gchar *name;
- gint i;
-
- for (i=0; i < sizeof(states_to_track)/sizeof(AtkStateType); i++)
- {
- one_state = (AtkStateType) states_to_track[i];
- name = atk_state_type_get_name (one_state);
-
- if (name)
- {
- boolean_value =
- atk_state_set_contains_state (state_set, one_state);
- _print_key_value(tab_n, group_num, name,
- (gpointer)(&boolean_value), VALUE_BOOLEAN);
- }
- }
- }
-
- g_object_unref (state_set);
- return(group_num);
-}
-
-static gint
-_print_action (AtkAction *aobject)
-{
- const gchar *action_name;
- const gchar *action_description;
- const gchar *action_keybinding;
- gchar *label_str, *output_str;
- gint group_num;
- gint num_actions, j;
- TabNumber tab_n = ACTION;
- NameValue *nv;
-
- group_num = _print_groupname(tab_n, ACTION_INTERFACE,
- "Action Interface");
-
- num_actions = atk_action_get_n_actions (aobject);
- output_str = g_strdup_printf("%d", num_actions);
- _print_key_value(tab_n, group_num, "Number of Actions",
- (gpointer) output_str, VALUE_STRING);
- g_free(output_str);
-
- for (j = 0; j < num_actions; j++)
- {
- label_str = g_strdup_printf("Action %d Name", j + 1);
- action_name = atk_action_get_name (aobject, j);
- if (action_name)
- {
- nv = _print_key_value(tab_n, group_num, label_str,
- (gpointer) action_name, VALUE_BUTTON);
- }
- else
- {
- nv = _print_key_value(tab_n, group_num, label_str, "NULL",
- VALUE_BUTTON);
- }
-
- nv->atkobj = ATK_OBJECT(aobject);
- nv->action_num = j;
- nv->signal_id = g_signal_connect (nv->button,
- "clicked", G_CALLBACK (_action_cb), nv);
-
- g_free(label_str);
-
- label_str = g_strdup_printf("Action %d Description", j + 1);
- action_description = atk_action_get_description (aobject, j);
- if (action_description)
- {
- _print_key_value(tab_n, group_num, label_str,
- (gpointer)action_description, VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num, label_str, "NULL",
- VALUE_STRING);
- }
- g_free(label_str);
-
- label_str = g_strdup_printf("Action %d Keybinding", j + 1);
- action_keybinding = atk_action_get_keybinding (aobject, j);
- if (action_keybinding)
- {
- _print_key_value(tab_n, group_num, label_str,
- (gpointer)action_keybinding, VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num, label_str, "NULL",
- VALUE_STRING);
- }
- g_free(label_str);
- }
- return(group_num);
-}
-
-static gint
-_print_component (AtkComponent *aobject)
-{
- gchar *output_str;
- gint x = 0;
- gint y = 0;
- gint width = 0;
- gint height = 0;
- gint group_num;
- TabNumber tab_n = COMPONENT;
-
- group_num = _print_groupname(tab_n, COMPONENT_INTERFACE,
- "Component Interface");
-
- atk_component_get_extents (aobject,
- &x, &y, &width, &height, ATK_XY_SCREEN);
-
- output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
- x, y, width, height);
- _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
- VALUE_STRING);
- g_free(output_str);
- return(group_num);
-}
-
-static gint
-_print_image (AtkImage *aobject)
-{
- const gchar *image_desc;
- gchar *output_str;
- gint x = 0;
- gint y = 0;
- gint height = 0;
- gint width = 0;
- gint group_num;
- TabNumber tab_n = IMAGE;
-
- group_num = _print_groupname(tab_n, IMAGE_INTERFACE,
- "Image Interface");
-
- image_desc = atk_image_get_image_description(aobject);
- if (image_desc)
- {
- _print_key_value(tab_n, group_num, "Description", (gpointer)image_desc,
- VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Description", "NULL",
- VALUE_STRING);
- }
-
- atk_image_get_image_position(aobject, &x, &y, ATK_XY_SCREEN);
- atk_image_get_image_size(aobject, &height, &width);
-
- output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
- x, y, width, height);
- _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
- VALUE_STRING);
- g_free(output_str);
- return(group_num);
-}
-
-static gint
-_print_selection (AtkSelection *aobject)
-{
- AtkObject *object;
- AtkRole role;
- gchar *label_str, *output_str;
- gint group_num;
- gint n_selected, j, n_selectable;
- TabNumber tab_n = SELECTION;
-
- group_num = _print_groupname(tab_n, SELECTION_INTERFACE,
- "Selection Interface");
-
- n_selected = atk_selection_get_selection_count (aobject);
- output_str = g_strdup_printf ("%d", n_selected);
- _print_key_value (tab_n, group_num, "Number of Selected Children",
- (gpointer) output_str, VALUE_STRING);
- g_free (output_str);
- /*
- * The number of selected items is the number of children except for
- * a ComboBox where it is the number of items in the list.
- */
- object = ATK_OBJECT (aobject);
- role = atk_object_get_role (object);
- if (role == ATK_ROLE_COMBO_BOX)
- {
- object = atk_object_ref_accessible_child (object, 0);
- g_return_val_if_fail (atk_object_get_role (object) == ATK_ROLE_LIST,
- group_num);
- n_selectable = atk_object_get_n_accessible_children (object);
- g_object_unref (G_OBJECT (object));
- }
- else
- {
- n_selectable = atk_object_get_n_accessible_children (object);
- }
- output_str = g_strdup_printf ("%d", n_selectable);
- _print_key_value (tab_n, group_num, "Number of Selectable Children",
- (gpointer) output_str, VALUE_STRING);
- g_free (output_str);
-
- for (j = 0; j < n_selected; j++)
- {
- const gchar *selected_name;
- AtkObject *selected_object;
-
- selected_object = atk_selection_ref_selection (aobject, j);
- selected_name = atk_object_get_name (selected_object);
- if (selected_name == NULL)
- {
- selected_name = "No name";
- }
- label_str = g_strdup_printf ("Selected item: %d Name", j+1);
- _print_key_value (tab_n, group_num, label_str,
- (gpointer) selected_name, VALUE_STRING);
- g_free (label_str);
- g_object_unref (G_OBJECT (selected_object));
- }
- return group_num;
-}
-
-static gint
-_print_table (AtkTable *aobject)
-{
- gchar *label_str, *output_str;
- const gchar *col_desc;
- AtkObject *caption;
- gint n_cols, n_rows;
- gint i;
- gint group_num;
- TabNumber tab_n = TABLE;
-
- group_num = _print_groupname(tab_n, TABLE_INTERFACE,
- "Table Interface");
-
- n_cols = atk_table_get_n_columns(aobject);
- output_str = g_strdup_printf("%d", n_cols);
- _print_key_value(tab_n, group_num, "Number Columns", (gpointer)output_str,
- VALUE_STRING);
- g_free(output_str);
-
- n_rows = atk_table_get_n_rows(aobject);
- output_str = g_strdup_printf("%d", n_rows);
- _print_key_value(tab_n, group_num, "Number Rows", (gpointer)output_str,
- VALUE_STRING);
- g_free(output_str);
-
- caption = atk_table_get_caption(aobject);
- if (caption)
- {
- const gchar* caption_name;
-
- caption_name = atk_object_get_name (caption);
- if (caption_name)
- {
- _print_key_value(tab_n, group_num, "Caption Name",
- (gpointer)caption_name, VALUE_STRING);
- }
- }
-
- for (i=0; i < n_cols; i++)
- {
- label_str = g_strdup_printf("Column %d Description", i + 1);
-
- col_desc = atk_table_get_column_description(aobject, i);
- if (col_desc)
- {
- _print_key_value(tab_n, group_num, label_str, (gpointer)col_desc,
- VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num, label_str, "NULL",
- VALUE_STRING);
- }
-
- g_free(label_str);
- }
-
- return(group_num);
-}
-
-static gint
-_print_text (AtkText *aobject)
-{
- gchar *output_str, *text_val, *text_val_escaped;
- gint n_chars, caret_offset;
- gint start_offset, end_offset;
- gint group_num;
- gint x, y, w, h;
- TabNumber tab_n = TEXT;
-
- group_num = _print_groupname(tab_n, TEXT_INTERFACE,
- "Text Content");
-
- n_chars = atk_text_get_character_count(aobject);
-
- output_str = g_strdup_printf("%d", n_chars);
- _print_key_value(tab_n, group_num, "Total Character Count",
- (gpointer)output_str, VALUE_STRING);
- g_free(output_str);
-
- /*
- * Pass through g_strescape so that non-ASCII chars are made
- * print-able.
- */
- text_val = atk_text_get_text (aobject, 0, n_chars);
- if (text_val)
- {
- text_val_escaped = g_strescape(text_val, NULL);
- _print_key_value (tab_n, group_num, "Text", (gpointer)text_val_escaped,
- VALUE_TEXT);
- g_free (text_val);
- g_free (text_val_escaped);
- }
- else
- {
- _print_key_value (tab_n, group_num, "Text", "NULL", VALUE_TEXT);
- }
-
- caret_offset = atk_text_get_caret_offset(aobject);
- output_str = g_strdup_printf("%d", caret_offset);
- _print_key_value(tab_n, group_num, "Caret Offset", (gpointer)output_str,
- VALUE_STRING);
- g_free(output_str);
-
- if (caret_offset < 0)
- return(group_num);
-
- text_val = atk_text_get_text_at_offset (aobject, caret_offset,
- ATK_TEXT_BOUNDARY_CHAR,
- &start_offset, &end_offset);
- if (text_val)
- {
- text_val_escaped = g_strescape(text_val, NULL);
- _print_key_value(tab_n, group_num, "Current Character",
- (gpointer)text_val_escaped, VALUE_STRING);
- g_free (text_val);
- g_free (text_val_escaped);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Current Character", "none",
- VALUE_STRING);
- }
-
- atk_text_get_character_extents (aobject, caret_offset,
- &x, &y, &w, &h, ATK_XY_SCREEN);
- output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
- if (output_str)
- {
- _print_key_value(tab_n, group_num, "Character Bounds (screen)",
- (gpointer)output_str, VALUE_STRING);
- g_free(output_str);
- }
-
- atk_text_get_character_extents (aobject, caret_offset,
- &x, &y, &w, &h, ATK_XY_WINDOW);
- output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
- if (output_str)
- {
- _print_key_value(tab_n, group_num, "Character Bounds (window)",
- (gpointer)output_str, VALUE_STRING);
- g_free(output_str);
- }
-
- text_val = atk_text_get_text_at_offset (aobject, caret_offset,
- ATK_TEXT_BOUNDARY_WORD_START,
- &start_offset, &end_offset);
- if (text_val)
- {
- text_val_escaped = g_strescape(text_val, NULL);
- _print_key_value(tab_n, group_num, "Current Word",
- (gpointer)text_val_escaped, VALUE_STRING);
- g_free (text_val);
- g_free (text_val_escaped);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Current Word", "none",
- VALUE_STRING);
- }
-
- text_val = atk_text_get_text_at_offset (aobject, caret_offset,
- ATK_TEXT_BOUNDARY_LINE_START,
- &start_offset, &end_offset);
- if (text_val)
- {
- text_val_escaped = g_strescape(text_val, NULL);
- _print_key_value(tab_n, group_num, "Current Line",
- (gpointer)text_val_escaped, VALUE_STRING);
- g_free (text_val);
- g_free (text_val_escaped);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Current Line", "none",
- VALUE_STRING);
- }
-
- text_val = atk_text_get_text_at_offset (aobject, caret_offset,
- ATK_TEXT_BOUNDARY_SENTENCE_START,
- &start_offset, &end_offset);
- if (text_val)
- {
- text_val_escaped = g_strescape(text_val, NULL);
- _print_key_value(tab_n, group_num, "Current Sentence",
- (gpointer)text_val_escaped, VALUE_STRING);
- g_free (text_val);
- g_free (text_val_escaped);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Current Line", "none",
- VALUE_STRING);
- }
- return(group_num);
-}
-
-static gint
-_print_text_attributes (AtkText *aobject)
-{
- AtkAttributeSet *attribute_set;
- AtkAttribute *attribute;
- gchar *output_str, *label_str;
- gint start_offset, end_offset, caret_offset;
- gint attribute_set_len, attribute_offset, i;
- gint group_num;
- TabNumber tab_n = TEXT;
-
- group_num = _print_groupname (tab_n, TEXT_ATTRIBUTES,
- "Text Attributes at Caret");
-
- caret_offset = atk_text_get_caret_offset(aobject);
- attribute_offset = caret_offset;
-
- start_offset = 0;
- end_offset = 0;
-
- attribute_set = atk_text_get_run_attributes(aobject, attribute_offset,
- &start_offset, &end_offset);
-
- label_str = g_strdup_printf("Attribute run start");
-
- output_str = g_strdup_printf("%d", start_offset);
- _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
- VALUE_STRING);
- g_free(label_str);
- g_free(output_str);
-
- label_str = g_strdup_printf("Attribute run end");
- output_str = g_strdup_printf("%d", end_offset);
- _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
- VALUE_STRING);
- g_free(label_str);
- g_free(output_str);
-
- if (attribute_set == NULL)
- attribute_set_len = 0;
- else
- attribute_set_len = g_slist_length(attribute_set);
-
- label_str = g_strdup_printf("Number of Attributes");
- output_str = g_strdup_printf("%d", attribute_set_len);
- _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
- VALUE_STRING);
- g_free(label_str);
- g_free(output_str);
-
- for (i=0; i < attribute_set_len; i++)
- {
- attribute = ((AtkAttribute *) g_slist_nth(attribute_set, i)->data);
-
- _print_key_value(tab_n, group_num, attribute->name,
- (gpointer)attribute->value, VALUE_STRING);
- }
- if (attribute_set != NULL)
- atk_attribute_set_free(attribute_set);
-
-
- return(group_num);
-}
-
-static gint
-_print_value (AtkValue *aobject)
-{
- GValue *value_back, val;
- gint group_num;
- TabNumber tab_n = VALUE;
-
- value_back = &val;
-
- group_num = _print_groupname(tab_n, VALUE_INTERFACE,
- "Value Interface");
-
- atk_value_get_current_value(aobject, value_back);
- _print_value_type(group_num, "Value", value_back);
- atk_value_get_minimum_value(aobject, value_back);
- _print_value_type(group_num, "Minimum Value", value_back);
- atk_value_get_maximum_value(aobject, value_back);
- _print_value_type(group_num, "Maximum Value", value_back);
- return(group_num);
-}
-
-static void
-_print_value_type(gint group_num, gchar *type, GValue *value)
-{
- gchar *label_str = NULL;
- gchar *output_str = NULL;
- TabNumber tab_n = VALUE;
-
- if (G_VALUE_HOLDS_DOUBLE (value))
- {
- label_str = g_strdup_printf("%s - Double", type);
- output_str = g_strdup_printf("%f",
- g_value_get_double (value));
- _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
- VALUE_STRING);
- }
- else if (G_VALUE_HOLDS_INT (value))
- {
- label_str = g_strdup_printf("%s - Integer", type);
- output_str = g_strdup_printf("%d",
- g_value_get_int (value));
- _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
- VALUE_STRING);
- }
- else
- {
- _print_key_value(tab_n, group_num, "Value", "Unknown Type",
- VALUE_STRING);
- }
-
- if (label_str)
- g_free(label_str);
- if (output_str)
- g_free(output_str);
-}
-
-static void
-_create_event_watcher (void)
-{
- focus_tracker_id = atk_add_focus_tracker (_print_accessible);
-
- if (track_mouse)
- {
- mouse_watcher_focus_id =
- atk_add_global_event_listener(_mouse_watcher,
- "Gtk:GtkWidget:enter_notify_event");
- mouse_watcher_button_id =
- atk_add_global_event_listener(_button_watcher,
- "Gtk:GtkWidget:button_press_event");
- }
-}
-
-static gboolean
-_mouse_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- GtkWidget *widget;
-
- object = g_value_get_object (param_values + 0);
-
- if (GTK_IS_MENU(object)) return TRUE;
-
- g_assert (GTK_IS_WIDGET(object));
-
- widget = GTK_WIDGET (object);
- if (GTK_IS_WINDOW (widget))
- {
- GtkWidget *focus_widget = gtk_window_get_focus (GTK_WINDOW (widget));
- if (focus_widget != NULL)
- widget = focus_widget;
- }
-
- _print_accessible (gtk_widget_get_accessible (widget));
- return TRUE;
-}
-
-static gboolean
-_button_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- GtkWidget *widget;
-
- object = g_value_get_object (param_values + 0);
-
- widget = GTK_WIDGET (object);
- if (GTK_IS_CONTAINER (widget))
- {
- if (G_VALUE_HOLDS_BOXED (param_values + 1))
- {
- GdkEventButton *event;
- gpointer gp;
- AtkObject *aobject;
- AtkObject *child;
- gint aobject_x, aobject_y;
- gint x, y;
-
- gp = g_value_get_boxed (param_values + 1);
- event = (GdkEventButton *) gp;
- aobject = gtk_widget_get_accessible (widget);
- aobject_x = aobject_y = 0;
- atk_component_get_position (ATK_COMPONENT (aobject),
- &aobject_x, &aobject_y,
- ATK_XY_WINDOW);
- x = aobject_x + (gint) event->x;
- y = aobject_y + (gint) event->y;
- child = atk_component_ref_accessible_at_point (ATK_COMPONENT (aobject),
- x,
- y,
- ATK_XY_WINDOW);
- if (child)
- {
- _print_accessible (child);
- g_object_unref (child);
- }
- else
- {
- if (!GTK_IS_MENU_ITEM (widget))
- {
- g_print ("No child at position %d %d for %s\n",
- x,
- y,
- g_type_name (G_OBJECT_TYPE (widget)));
- }
- }
- }
- }
-
- return TRUE;
-}
-
-static void _add_notebook_page (GtkNotebook *nbook,
- GtkWidget *content_widget,
- GtkWidget **new_page,
- const gchar *label_text)
-{
- GtkWidget *label;
-
- if (content_widget != NULL)
- {
- *new_page = content_widget;
- }
- else
- {
- *new_page = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
- }
-
- label = gtk_label_new ("");
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), label_text);
- gtk_notebook_append_page (notebook, *new_page, label);
- gtk_widget_show(*new_page);
-}
-
-static void
-_create_notebook (void)
-{
- TabInfo *tab;
- notebook = GTK_NOTEBOOK (gtk_notebook_new());
-
- tab = nbook_tabs[OBJECT];
- _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Object</b>");
-
- tab = nbook_tabs[ACTION];
- _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Action</b>");
-
- tab = nbook_tabs[COMPONENT];
- _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Component</b>");
-
- tab = nbook_tabs[IMAGE];
- _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Image</b>");
-
- tab = nbook_tabs[SELECTION];
- _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Selection</b>");
-
- tab = nbook_tabs[TABLE];
- _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Table</b>");
-
- tab = nbook_tabs[TEXT];
- _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>Te_xt</b>");
-
- tab = nbook_tabs[VALUE];
- _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Value</b>");
-
- g_signal_connect (notebook,
- "switch-page",
- G_CALLBACK (_update_current_page),
- NULL);
-}
-
-static void
-_init_data(void)
-{
- TabInfo *the_tab;
-
- the_tab = g_new0(TabInfo, 1);
- the_tab->page = NULL;
- the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
- the_tab->name = "Object";
- nbook_tabs[OBJECT] = the_tab;
-
- the_tab = g_new0(TabInfo, 1);
- the_tab->page = NULL;
- the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
- the_tab->name = "Action";
- nbook_tabs[ACTION] = the_tab;
-
- the_tab = g_new0(TabInfo, 1);
- the_tab->page = NULL;
- the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
- the_tab->name = "Component";
- nbook_tabs[COMPONENT] = the_tab;
-
- the_tab = g_new0(TabInfo, 1);
- the_tab->page = NULL;
- the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
- the_tab->name = "Image";
- nbook_tabs[IMAGE] = the_tab;
-
- the_tab = g_new0(TabInfo, 1);
- the_tab->page = NULL;
- the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
- the_tab->name = "Selection";
- nbook_tabs[SELECTION] = the_tab;
-
- the_tab = g_new0(TabInfo, 1);
- the_tab->page = NULL;
- the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
- the_tab->name = "Table";
- nbook_tabs[TABLE] = the_tab;
-
- the_tab = g_new0(TabInfo, 1);
- the_tab->page = NULL;
- the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
- the_tab->name = "Text";
- nbook_tabs[TEXT] = the_tab;
-
- the_tab = g_new0(TabInfo, 1);
- the_tab->page = NULL;
- the_tab->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
- the_tab->name = "Value";
- nbook_tabs[VALUE] = the_tab;
-}
-
-static void
-_create_window (void)
-{
- static GtkWidget *window = NULL;
-
- if (!window)
- {
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_widget_set_name (window, "Ferret Window");
-
- g_signal_connect (window, "destroy",
- G_CALLBACK (gtk_widget_destroyed),
- &window);
-
- gtk_window_set_title (GTK_WINDOW (window), "GTK+ Ferret Output");
- gtk_window_set_default_size (GTK_WINDOW (window), 333, 550);
- gtk_container_set_border_width (GTK_CONTAINER (window), 0);
-
- vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_add (GTK_CONTAINER (window), vbox1);
- gtk_widget_show (vbox1);
-
- menubar = gtk_menu_bar_new ();
- gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, TRUE, 0);
- gtk_widget_show (menubar);
- menutop = gtk_menu_item_new_with_label("Menu");
- gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menutop);
- gtk_widget_show (menutop);
- menu = gtk_menu_new();
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (menutop), menu);
- gtk_widget_show (menu);
-
- _add_menu(&menu, &menuitem_trackmouse, "Track Mouse", track_mouse,
- G_CALLBACK(_toggle_trackmouse));
- _add_menu(&menu, &menuitem_trackfocus, "Track Focus", track_focus,
- G_CALLBACK(_toggle_trackfocus));
- _add_menu(&menu, &menuitem_magnifier, "Magnifier", use_magnifier,
- G_CALLBACK(_toggle_magnifier));
- _add_menu(&menu, &menuitem_festival, "Festival", use_festival,
- G_CALLBACK(_toggle_festival));
- _add_menu(&menu, &menuitem_festival_terse, "Festival Terse",
- (!say_role && !say_accel),
- G_CALLBACK(_toggle_festival_terse));
- _add_menu(&menu, &menuitem_terminal, "Terminal Output", display_ascii,
- G_CALLBACK(_toggle_terminal));
- _add_menu(&menu, &menuitem_no_signals, "No ATK Signals", no_signals,
- G_CALLBACK(_toggle_no_signals));
-
- _create_notebook ();
- gtk_container_add (GTK_CONTAINER (vbox1), GTK_WIDGET (notebook));
- gtk_widget_show (GTK_WIDGET (notebook));
- }
- if (!gtk_widget_get_visible (window))
- gtk_widget_show (window);
-
- mainWindow = GTK_WIDGET (window);
-}
-
-static void
-_add_menu(GtkWidget ** menu, GtkWidget ** menuitem, gchar * name,
- gboolean init_value, GCallback func)
-{
- *menuitem = gtk_check_menu_item_new_with_label(name);
- gtk_check_menu_item_set_active(
- GTK_CHECK_MENU_ITEM(*menuitem), init_value);
- gtk_menu_shell_append (GTK_MENU_SHELL (*menu), *menuitem);
- gtk_widget_show(*menuitem);
- g_signal_connect(*menuitem, "toggled", func, NULL);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- if (g_getenv ("FERRET_ASCII"))
- display_ascii = TRUE;
-
- if (g_getenv ("FERRET_NOSIGNALS"))
- no_signals = TRUE;
-
- if (display_ascii)
- g_print("GTK ferret Module loaded\n");
-
- if (g_getenv("FERRET_MAGNIFIER"))
- use_magnifier = TRUE;
-
- if (g_getenv ("FERRET_FESTIVAL"))
- use_festival = TRUE;
-
- if (g_getenv ("FERRET_MOUSETRACK"))
- track_mouse = TRUE;
-
- if (g_getenv ("FERRET_TERSE"))
- {
- say_role = FALSE;
- say_accel = FALSE;
- }
-
- _init_data();
-
- _create_window();
-
- _create_event_watcher();
-
- return 0;
-}
-
-static void
-_clear_tab(TabNumber tab_n)
-{
- GList *group_list, *nv_list;
- TabInfo *tab;
- GroupInfo *group;
- NameValue *nv;
-
- tab = nbook_tabs[tab_n];
-
- for (group_list = tab->groups; group_list; group_list = group_list->next)
- {
- group = (GroupInfo *) group_list->data;
-
- if (group->is_scrolled)
- gtk_widget_hide(GTK_WIDGET(group->scroll_outer_frame));
-
- gtk_widget_hide(GTK_WIDGET(group->frame));
- gtk_widget_hide(GTK_WIDGET(group->group_vbox));
-
- for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
- {
- nv = (NameValue *) nv_list->data;
- nv->active = FALSE;
- gtk_widget_hide(GTK_WIDGET(nv->column1));
- gtk_widget_hide(GTK_WIDGET(nv->column2));
- gtk_widget_hide(GTK_WIDGET(nv->label));
-
- switch (nv->type)
- {
- case VALUE_STRING:
- gtk_widget_hide(GTK_WIDGET(nv->string));
- break;
- case VALUE_BOOLEAN:
- gtk_widget_hide(GTK_WIDGET(nv->boolean));
- break;
- case VALUE_TEXT:
- gtk_widget_hide(GTK_WIDGET(nv->text));
- break;
- case VALUE_BUTTON:
- gtk_widget_hide(GTK_WIDGET(nv->button));
- break;
- }
- gtk_widget_hide(GTK_WIDGET(nv->hbox));
-
- /* Disconnect signal handler if any */
- if (nv->signal_id != -1)
- g_signal_handler_disconnect(nv->button, nv->signal_id);
-
- nv->signal_id = -1;
- }
- }
-}
-
-static gint
-_print_groupname(TabNumber tab_n, GroupId group_id,
- const char *groupname)
-{
- TabInfo *tab;
- GroupInfo *the_group;
- gint rc = -1;
-
- if (display_ascii)
- g_print("\n<%s>\n", groupname);
-
- tab = nbook_tabs[tab_n];
- the_group = _get_group(tab, group_id, groupname);
- rc = g_list_index(tab->groups, the_group);
- return rc;
-}
-
-static GroupInfo*
-_get_group(TabInfo *tab, GroupId group_id, const gchar *groupname)
-{
- GroupInfo *group = NULL;
- gboolean found = FALSE;
- GList *group_list;
-
- for (group_list = tab->groups; group_list; group_list = group_list->next)
- {
- group = (GroupInfo *) group_list->data;
- if (group_id == group->group_id)
- {
- found = TRUE;
- break;
- }
- }
-
- if (!found)
- {
- /* build a new one */
- group = (GroupInfo *)g_new0(GroupInfo, 1);
- group->group_id = group_id;
- _get_group_scrolled(group);
-
- if (group->is_scrolled)
- {
- group->frame = gtk_scrolled_window_new (NULL, NULL);
- gtk_widget_set_size_request (GTK_WIDGET (group->frame), -2,
- group->default_height);
- group->scroll_outer_frame = GTK_FRAME(gtk_frame_new(groupname));
- gtk_container_add(GTK_CONTAINER(group->scroll_outer_frame),
- group->frame);
- }
- else
- {
- group->frame = gtk_frame_new(groupname);
- }
-
- gtk_container_set_border_width(GTK_CONTAINER(group->frame), 10);
-
- group->name = g_strdup(groupname);
- group->group_vbox = GTK_BOX(gtk_box_new (GTK_ORIENTATION_VERTICAL, 10));
-
- if (group->is_scrolled)
- {
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (group->frame),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_add_with_viewport(
- GTK_SCROLLED_WINDOW(group->frame),
- GTK_WIDGET(group->group_vbox));
- }
- else
- {
- gtk_container_add(GTK_CONTAINER(group->frame),
- GTK_WIDGET(group->group_vbox));
- }
-
- tab->groups = g_list_append (tab->groups, group);
-
- if (group->is_scrolled)
- {
- gtk_box_pack_start (GTK_BOX (tab->main_box),
- GTK_WIDGET (group->scroll_outer_frame),
- TRUE, TRUE, 0);
- }
- else
- {
- gtk_box_pack_start (GTK_BOX (tab->main_box),
- GTK_WIDGET (group->frame),
- TRUE, TRUE, 0);
- }
- }
-
- return group;
-}
-
-void
-_get_group_scrolled(GroupInfo *group)
-{
- if (group->group_id == OBJECT_INTERFACE)
- {
- group->is_scrolled = FALSE;
- }
- else if (group->group_id == RELATION_INTERFACE)
- {
- group->is_scrolled = TRUE;
- group->default_height = 50;
- }
- else if (group->group_id == STATE_INTERFACE)
- {
- group->is_scrolled = TRUE;
- group->default_height = 100;
- }
- else if (group->group_id == ACTION_INTERFACE)
- {
- group->is_scrolled = TRUE;
- group->default_height = 200;
- }
- else if (group->group_id == TEXT_ATTRIBUTES)
- {
- group->is_scrolled = TRUE;
- group->default_height = 70;
- }
- else
- {
- group->is_scrolled = FALSE;
- }
-}
-
-NameValue *
-_get_name_value(GroupInfo *group, const gchar *label,
- gpointer value_ptr, ValueType type)
-{
- NameValue *name_value = NULL;
- GList *nv_list;
- GValue *value;
- gboolean found = FALSE;
- static char *empty_string = "";
-
- if (!label)
- {
- label = empty_string;
- }
-
- for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
- {
- name_value = (NameValue *) nv_list->data;
- if (!name_value->active)
- {
- found = TRUE;
- break;
- }
- }
-
- if (!found)
- {
- name_value = (NameValue *)g_new0(NameValue, 1);
- name_value->column1 = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10));
- name_value->column2 = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10));
- name_value->hbox = GTK_BOX(gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5));
- name_value->label = GTK_LABEL(gtk_label_new(label));
- name_value->string = gtk_label_new (NULL);
- name_value->boolean = gtk_check_button_new ();
- gtk_entry_buffer_set_max_length (gtk_entry_get_buffer (GTK_ENTRY (name_value->text)), 1000);
- name_value->button = GTK_BUTTON(gtk_button_new ());
-
- gtk_box_pack_end(GTK_BOX(name_value->column1),
- GTK_WIDGET(name_value->label), FALSE, FALSE, 10);
-
- switch (type)
- {
- case VALUE_STRING:
- gtk_label_set_text(GTK_LABEL(name_value->string),
- (gchar *) value_ptr);
- gtk_box_pack_start(GTK_BOX(name_value->column2),
- GTK_WIDGET(name_value->string), FALSE, FALSE, 10);
- break;
- case VALUE_BOOLEAN:
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
- *((gboolean *)value_ptr));
- gtk_widget_set_sensitive(name_value->boolean, FALSE);
- gtk_box_pack_start(GTK_BOX(name_value->column2),
- GTK_WIDGET(name_value->boolean), FALSE, FALSE, 10);
- break;
- case VALUE_TEXT:
- gtk_entry_set_text (GTK_ENTRY (name_value->text),
- (gchar *)value_ptr);
- gtk_box_pack_start(GTK_BOX(name_value->column2),
- GTK_WIDGET(name_value->text), FALSE, FALSE, 10);
- case VALUE_BUTTON:
- value = &(name_value->button_gval);
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_STRING);
- g_value_set_string (value, (gchar *)value_ptr);
- g_object_set_property(G_OBJECT(name_value->button),
- "label", value);
- gtk_box_pack_start(GTK_BOX(name_value->column2),
- GTK_WIDGET(name_value->button), FALSE, FALSE, 10);
- break;
- }
-
- gtk_box_pack_start (GTK_BOX (name_value->hbox),
- GTK_WIDGET (name_value->column1),
- TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (name_value->hbox),
- GTK_WIDGET (name_value->column2),
- TRUE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(group->group_vbox),
- GTK_WIDGET(name_value->hbox));
- group->name_value = g_list_append (group->name_value, name_value);
- }
- else
- {
- gtk_label_set_text(GTK_LABEL(name_value->label), label);
- switch (type)
- {
- case VALUE_STRING:
- gtk_label_set_text(GTK_LABEL(name_value->string),
- (gchar *) value_ptr);
- break;
- case VALUE_BOOLEAN:
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
- *((gboolean *)value_ptr));
- gtk_widget_set_sensitive(name_value->boolean, FALSE);
- break;
- case VALUE_TEXT:
- gtk_entry_set_text (GTK_ENTRY (name_value->text),
- (gchar *) value_ptr);
- break;
- case VALUE_BUTTON:
- value = &(name_value->button_gval);
- memset (value, 0, sizeof (GValue));
- g_value_init (value, G_TYPE_STRING);
- g_value_set_string (value, (gchar *)value_ptr);
- g_object_set_property(G_OBJECT(name_value->button),
- "label", value);
- break;
- }
- }
-
- name_value->active = TRUE;
- name_value->type = type;
- name_value->signal_id = -1;
-
- gtk_widget_show(GTK_WIDGET(name_value->label));
-
- switch (type)
- {
- case VALUE_STRING:
- gtk_widget_show(GTK_WIDGET(name_value->string));
- break;
- case VALUE_BOOLEAN:
- gtk_widget_show(GTK_WIDGET(name_value->boolean));
- break;
- case VALUE_TEXT:
- gtk_widget_show(GTK_WIDGET(name_value->text));
- break;
- case VALUE_BUTTON:
- gtk_widget_show(GTK_WIDGET(name_value->button));
- break;
- }
-
- gtk_widget_show(GTK_WIDGET(name_value->column1));
- gtk_widget_show(GTK_WIDGET(name_value->column2));
- gtk_widget_show(GTK_WIDGET(name_value->hbox));
- gtk_widget_show(GTK_WIDGET(group->group_vbox));
-
- return name_value;
-}
-
-static NameValue *
-_print_key_value(TabNumber tab_n, gint group_number,
- const char *label, gpointer value, ValueType type)
-{
- TabInfo *tab;
- GroupInfo *the_group;
-
- if (display_ascii)
- {
- if (type == VALUE_BOOLEAN)
- {
- if (*((gboolean *)value))
- g_print("\t%-30s\tTRUE\n", label);
- else
- g_print("\t%-30s\tFALSE\n", label);
- }
- else
- {
- g_print("\t%-30s\t%s\n", label,
- value ? (gchar *)value : "NULL");
- }
- }
-
- tab = nbook_tabs[tab_n];
- the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
- return _get_name_value(the_group, label, (gpointer)value, type);
-}
-
-static void
-_finished_group(TabNumber tab_no, gint group_number)
-{
- TabInfo *tab;
- GroupInfo *the_group;
-
- tab = nbook_tabs[tab_no];
-
- the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
-
- if (the_group->is_scrolled)
- gtk_widget_show(GTK_WIDGET(the_group->scroll_outer_frame));
-
- gtk_widget_show(GTK_WIDGET(the_group->frame));
- gtk_widget_show(GTK_WIDGET(the_group->group_vbox));
- gtk_widget_show(GTK_WIDGET(tab->main_box));
-}
-
-/* Signal handlers */
-
-static gulong child_added_id = 0;
-static gulong child_removed_id = 0;
-static gulong state_change_id = 0;
-
-static gulong text_caret_handler_id = 0;
-static gulong text_inserted_id = 0;
-static gulong text_deleted_id = 0;
-
-static gulong table_row_inserted_id = 0;
-static gulong table_column_inserted_id = 0;
-static gulong table_row_deleted_id = 0;
-static gulong table_column_deleted_id = 0;
-static gulong table_row_reordered_id = 0;
-static gulong table_column_reordered_id = 0;
-
-static gulong property_id = 0;
-
-static void
-_update_handlers(AtkObject *obj)
-{
- /* Remove signal handlers from object that had focus before */
-
- if (last_object != NULL && G_TYPE_CHECK_INSTANCE(last_object))
- {
- if (child_added_id != 0)
- g_signal_handler_disconnect(last_object, child_added_id);
- if (child_removed_id != 0)
- g_signal_handler_disconnect(last_object, child_removed_id);
- if (state_change_id != 0)
- g_signal_handler_disconnect(last_object, state_change_id);
-
- if (text_caret_handler_id != 0)
- g_signal_handler_disconnect(last_object, text_caret_handler_id);
- if (text_inserted_id != 0)
- g_signal_handler_disconnect(last_object, text_inserted_id);
- if (text_deleted_id != 0)
- g_signal_handler_disconnect(last_object, text_deleted_id);
-
- if (table_row_inserted_id != 0)
- g_signal_handler_disconnect(last_object, table_row_inserted_id);
- if (table_column_inserted_id != 0)
- g_signal_handler_disconnect(last_object, table_column_inserted_id);
- if (table_row_deleted_id != 0)
- g_signal_handler_disconnect(last_object, table_row_deleted_id);
- if (table_column_deleted_id != 0)
- g_signal_handler_disconnect(last_object, table_column_deleted_id);
- if (table_row_reordered_id != 0)
- g_signal_handler_disconnect(last_object, table_row_reordered_id);
- if (table_column_reordered_id != 0)
- g_signal_handler_disconnect(last_object, table_column_reordered_id);
- if (property_id != 0)
- g_signal_handler_disconnect(last_object, property_id);
-
- g_object_unref(last_object);
- }
-
- last_object = NULL;
-
- child_added_id = 0;
- child_removed_id = 0;
- text_caret_handler_id = 0;
- text_inserted_id = 0;
- text_deleted_id = 0;
- table_row_inserted_id = 0;
- table_column_inserted_id = 0;
- table_row_deleted_id = 0;
- table_column_deleted_id = 0;
- table_row_reordered_id = 0;
- table_column_reordered_id = 0;
- property_id = 0;
-
- if (!G_TYPE_CHECK_INSTANCE(obj))
- return;
-
- g_object_ref(obj);
- last_object = obj;
-
- /* Add signal handlers to object that now has focus. */
-
- if (ATK_IS_OBJECT(obj))
- {
- child_added_id = g_signal_connect_closure (obj,
- "children_changed::add",
- g_cclosure_new (G_CALLBACK (_notify_object_child_added),
- NULL, NULL), FALSE);
-
- child_removed_id = g_signal_connect_closure (obj,
- "children_changed::remove",
- g_cclosure_new (G_CALLBACK (_notify_object_child_removed),
- NULL, NULL), FALSE);
-
- state_change_id = g_signal_connect_closure (obj,
- "state_change",
- g_cclosure_new (G_CALLBACK (_notify_object_state_change),
- NULL, NULL), FALSE);
- }
-
- if (ATK_IS_TEXT(obj))
- {
- text_caret_handler_id = g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("text_caret_moved", G_OBJECT_TYPE (obj)),
- 0, g_cclosure_new (G_CALLBACK (_notify_caret_handler),
- NULL, NULL), FALSE);
- text_inserted_id = g_signal_connect_closure (obj,
- "text_changed::insert",
- g_cclosure_new (G_CALLBACK (_notify_text_insert_handler),
- NULL, NULL), FALSE);
- text_deleted_id = g_signal_connect_closure (obj,
- "text_changed::delete",
- g_cclosure_new (G_CALLBACK (_notify_text_delete_handler),
- NULL, NULL), FALSE);
- }
-
- if (ATK_IS_TABLE(obj))
- {
- table_row_inserted_id = g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("row_inserted", G_OBJECT_TYPE (obj)),
- 0, g_cclosure_new (G_CALLBACK (_notify_table_row_inserted),
- NULL, NULL), FALSE);
- table_column_inserted_id = g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("column_inserted", G_OBJECT_TYPE (obj)),
- 0, g_cclosure_new (G_CALLBACK (_notify_table_column_inserted),
- NULL, NULL), FALSE);
- table_row_deleted_id = g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("row_deleted", G_OBJECT_TYPE (obj)),
- 0, g_cclosure_new (G_CALLBACK (_notify_table_row_deleted),
- NULL, NULL), FALSE);
- table_column_deleted_id = g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("column_deleted", G_OBJECT_TYPE (obj)),
- 0, g_cclosure_new (G_CALLBACK (_notify_table_column_deleted),
- NULL, NULL), FALSE);
- table_row_reordered_id = g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("row_reordered", G_OBJECT_TYPE (obj)),
- 0, g_cclosure_new (G_CALLBACK (_notify_table_row_reordered),
- NULL, NULL), FALSE);
- table_column_reordered_id = g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("column_reordered", G_OBJECT_TYPE (obj)),
- 0, g_cclosure_new (G_CALLBACK (_notify_table_column_reordered),
- NULL, NULL), FALSE);
- }
-
- property_id = g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("property_change", G_OBJECT_TYPE (obj)),
- 0, g_cclosure_new (G_CALLBACK (_property_change_handler),
- NULL, NULL),
- FALSE);
-}
-
-/* Text signals */
-
-static void
-_notify_text_insert_handler (GObject *obj, int position, int offset)
-{
- gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
- gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
- position, offset, text ? text: "<NULL>");
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
- "Text Insert", output_str);
- g_free(output_str);
-}
-
-static void
-_notify_text_delete_handler (GObject *obj, int position, int offset)
-{
- gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
- gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
- position, offset, text ? text: "<NULL>");
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
- "Text Delete", output_str);
- g_free(output_str);
-}
-
-static void
-_notify_caret_handler (GObject *obj, int position)
-{
- gchar *output_str = g_strdup_printf("position %d", position);
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
- "Text Caret Moved", output_str);
- g_free(output_str);
-}
-
-/* Table signals */
-
-static void
-_notify_table_row_inserted (GObject *obj, gint start_offset,
- gint length)
-{
- gchar *output_str =
- g_strdup_printf("position %d, num of rows inserted %d!\n",
- start_offset, length);
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
- "Table Row Inserted", output_str);
- g_free(output_str);
-}
-
-static void
-_notify_table_column_inserted (GObject *obj, gint start_offset,
- gint length)
-{
- gchar *output_str =
- g_strdup_printf("position %d, num of rows inserted %d!\n",
- start_offset, length);
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
- "Table Column Inserted", output_str);
- g_free(output_str);
-}
-
-static void
-_notify_table_row_deleted (GObject *obj, gint start_offset,
- gint length)
-{
- gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
- start_offset, length);
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
- "Table Row Deleted", output_str);
- g_free(output_str);
-}
-
-static void
-_notify_table_column_deleted (GObject *obj, gint start_offset,
- gint length)
-{
- gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
- start_offset, length);
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
- "Table Column Deleted", output_str);
- g_free(output_str);
-}
-
-static void
-_notify_table_row_reordered (GObject *obj)
-{
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
- "Table Row Reordered", NULL);
-}
-
-static void
-_notify_table_column_reordered (GObject *obj)
-{
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
- "Table Column Reordered", NULL);
-}
-
-/* Object signals */
-
-static void
-_notify_object_child_added (GObject *obj, gint index,
- AtkObject *child)
-{
- gchar *output_str = g_strdup_printf("index %d", index);
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
- "Child Added", output_str);
- g_free(output_str);
-}
-
-static void
-_notify_object_child_removed (GObject *obj, gint index,
- AtkObject *child)
-{
- gchar *output_str = g_strdup_printf("index %d", index);
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
- "Child Removed", output_str);
- g_free(output_str);
-}
-
-static void
-_notify_object_state_change (GObject *obj, gchar *name, gboolean set)
-{
- gchar *output_str = g_strdup_printf("name %s %s set",
- name, set ? "is" : "was");
- _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
- "State Change", output_str);
- g_free(output_str);
-}
-
-
-/* Function to print signals */
-
-static void
-_print_signal(AtkObject *aobject, FerretSignalType type,
- const char *name, const char *info)
-{
- TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
-
- if (no_signals)
- return;
-
- if (display_ascii)
- {
- if (info != NULL)
- g_print("SIGNAL:\t%-34s\t%s\n", name, info);
- else
- g_print("SIGNAL:\t%-34s\n", name);
- }
-
- if (use_festival)
- {
- if ((type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
- {
- _speak_caret_event (aobject);
- }
- else if (type == FERRET_SIGNAL_TEXT)
- {
- last_caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
- }
- }
-
- if (use_magnifier && ATK_IS_TEXT (aobject) &&
- (type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
- {
- gint x, y, w, h;
- gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
- atk_text_get_character_extents ( ATK_TEXT (aobject), caret_offset, &x, &y, &w, &h, ATK_XY_SCREEN);
- _send_to_magnifier (x, y, w, h);
- }
-
- if ((type == FERRET_SIGNAL_TEXT && top_tab == TEXT) ||
- (type == FERRET_SIGNAL_TABLE && top_tab == TABLE) ||
- (type == FERRET_SIGNAL_OBJECT && top_tab == OBJECT))
- {
- if (display_ascii)
- g_print("Updating tab\n");
-
- _update(top_tab, aobject);
- }
-}
-
-/* Update functions */
-
-static void
-_update (TabNumber top_tab, AtkObject *aobject)
-{
- gint group_num;
-
- if (top_tab >= OBJECT && top_tab < END_TABS)
- {
- _clear_tab(top_tab);
- }
-
- if (top_tab == OBJECT && ATK_IS_OBJECT(aobject))
- {
- group_num = _print_object(aobject);
- _finished_group(OBJECT, group_num);
- group_num = _print_relation(aobject);
- _finished_group(OBJECT, group_num);
- group_num = _print_state(aobject);
- _finished_group(OBJECT, group_num);
- }
- if (top_tab == TEXT && ATK_IS_TEXT(aobject))
- {
- group_num = _print_text(ATK_TEXT (aobject));
- _finished_group(TEXT, group_num);
- group_num = _print_text_attributes(ATK_TEXT (aobject));
- _finished_group(TEXT, group_num);
- }
- if (top_tab == SELECTION && ATK_IS_SELECTION(aobject))
- {
- group_num = _print_selection(ATK_SELECTION (aobject));
- _finished_group(SELECTION, group_num);
- }
- if (top_tab == TABLE && ATK_IS_TABLE(aobject))
- {
- group_num = _print_table(ATK_TABLE (aobject));
- _finished_group(TABLE, group_num);
- }
- if (top_tab == ACTION && ATK_IS_ACTION(aobject))
- {
- group_num = _print_action(ATK_ACTION (aobject));
- _finished_group(ACTION, group_num);
- }
- if (top_tab == COMPONENT && ATK_IS_COMPONENT(aobject))
- {
- group_num = _print_component(ATK_COMPONENT(aobject));
- _finished_group(COMPONENT, group_num);
- }
- if (top_tab == IMAGE && ATK_IS_IMAGE(aobject))
- {
- group_num = _print_image(ATK_IMAGE (aobject));
- _finished_group(IMAGE, group_num);
- }
- if (top_tab == VALUE && ATK_IS_VALUE(aobject))
- {
- group_num = _print_value(ATK_VALUE(aobject));
- _finished_group(VALUE, group_num);
- }
-}
-
-static void
-_update_current_page(GtkNotebook *notebook, gpointer p, guint current_page)
-{
- _update(current_page+OBJECT, last_object);
-}
-
-/* Property listeners */
-
-static void _property_change_handler (AtkObject *obj,
- AtkPropertyValues *values)
-{
- TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
-
- if (no_signals)
- return;
-
- /*
- * Only process if the property change corrisponds to the current
- * object
- */
- if (obj != last_object)
- {
- if (display_ascii)
- {
- g_print("\nProperty change event <%s> for object not in focus\n",
- values->property_name);
- }
-
- return;
- }
-
- if (display_ascii)
- {
- g_print("\nProperty change event <%s> occurred.\n",
- values->property_name);
- }
-
- /*
- * Update the top tab if a property changes.
- *
- * We may be able to ignore some property changes if they do not
- * change anything in ferret.
- */
-
- if (top_tab == OBJECT &&
- ((strcmp (values->property_name, "accessible-name") == 0) ||
- (strcmp (values->property_name, "accessible-description") == 0) ||
- (strcmp (values->property_name, "accessible-parent") == 0) ||
- (strcmp (values->property_name, "accessible-value") == 0) ||
- (strcmp (values->property_name, "accessible-role") == 0) ||
- (strcmp (values->property_name, "accessible-component-layout") == 0) ||
- (strcmp (values->property_name, "accessible-component-mdi-zorder") == 0) ||
- (strcmp (values->property_name, "accessible-table-caption") == 0) ||
- (strcmp (values->property_name,
- "accessible-table-column-description") == 0) ||
- (strcmp (values->property_name,
- "accessible-table-column-header") == 0) ||
- (strcmp (values->property_name,
- "accessible-table-row-description") == 0) ||
- (strcmp (values->property_name,
- "accessible-table-row-header") == 0) ||
- (strcmp (values->property_name, "accessible-table-summary") == 0)))
- {
- if (display_ascii)
- g_print("Updating tab\n");
-
- _update(top_tab, last_object);
- }
- else if (top_tab == VALUE &&
- (strcmp (values->property_name, "accessible-value") == 0))
- {
- if (display_ascii)
- g_print("Updating tab\n");
-
- _update(top_tab, last_object);
- }
-}
-
-/* Action button callback function */
-
-void _action_cb(GtkWidget *widget, gpointer *userdata)
-{
- NameValue *nv = (NameValue *)userdata;
- atk_action_do_action(ATK_ACTION(nv->atkobj), nv->action_num);
-}
-
-/* Menu-bar callback functions */
-
-void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data)
-{
- if (gtk_check_menu_item_get_active (checkmenuitem))
- display_ascii = TRUE;
- else
- display_ascii = FALSE;
-}
-
-void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data)
-{
- if (gtk_check_menu_item_get_active (checkmenuitem))
- no_signals = TRUE;
- else
- no_signals = FALSE;
-}
-
-void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data)
-{
- if (gtk_check_menu_item_get_active (checkmenuitem))
- use_magnifier = TRUE;
- else
- use_magnifier = FALSE;
-}
-
-void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data)
-{
- if (gtk_check_menu_item_get_active (checkmenuitem))
- use_festival = TRUE;
- else
- use_festival = FALSE;
-}
-
-void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data)
-{
- if (gtk_check_menu_item_get_active (checkmenuitem))
- {
- say_role = FALSE;
- say_accel = FALSE;
- }
- else
- {
- say_role = TRUE;
- say_accel = TRUE;
- }
-}
-
-void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data)
-{
- if (gtk_check_menu_item_get_active (checkmenuitem))
- {
- mouse_watcher_focus_id =
- atk_add_global_event_listener(_mouse_watcher,
- "Gtk:GtkWidget:enter_notify_event");
- mouse_watcher_button_id =
- atk_add_global_event_listener(_button_watcher,
- "Gtk:GtkWidget:button_press_event");
- track_mouse = TRUE;
- }
- else
- {
- if (mouse_watcher_focus_id != -1)
- {
- atk_remove_global_event_listener(mouse_watcher_focus_id);
- atk_remove_global_event_listener(mouse_watcher_button_id);
- track_mouse = FALSE;
- }
- }
-}
-
-void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
- gpointer user_data)
-{
- if (gtk_check_menu_item_get_active (checkmenuitem))
- {
- track_focus = TRUE;
- focus_tracker_id = atk_add_focus_tracker (_print_accessible);
- }
- else
- {
- g_print ("No longer tracking focus.\n");
- track_focus = FALSE;
- atk_remove_focus_tracker (focus_tracker_id);
- }
-}
+++ /dev/null
-#include <string.h>
-#include <stdlib.h>
-#include <gtk/gtk.h>
-#include "testlib.h"
-
-/*
- * This module is used to test the implementation of AtkAction,
- * i.e. the getting of the name and the getting and setting of description
- */
-
-static void _create_event_watcher (void);
-static void _check_object (AtkObject *obj);
-
-static void
-_check_object (AtkObject *obj)
-{
- const char *accessible_name;
- const gchar * typename = NULL;
-
- if (GTK_IS_ACCESSIBLE (obj))
- {
- GtkWidget* widget = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- typename = g_type_name (G_OBJECT_TYPE (widget));
- g_print ("Widget type name: %s\n", typename ? typename : "NULL");
- }
- typename = g_type_name (G_OBJECT_TYPE (obj));
- g_print ("Accessible type name: %s\n", typename ? typename : "NULL");
- accessible_name = atk_object_get_name (obj);
- if (accessible_name)
- g_print ("Name: %s\n", accessible_name);
-
- if (ATK_IS_ACTION (obj))
- {
- AtkAction *action = ATK_ACTION (obj);
- gint n_actions, i;
- const gchar *action_name;
- const gchar *action_desc;
- const gchar *action_binding;
- const gchar *desc = "Test description";
-
- n_actions = atk_action_get_n_actions (action);
- g_print ("AtkAction supported number of actions: %d\n", n_actions);
- for (i = 0; i < n_actions; i++)
- {
- action_name = atk_action_get_name (action, i);
- g_print ("Name of Action %d: %s\n", i, action_name);
- action_binding = atk_action_get_keybinding (action, i);
- if (action_binding)
- g_print ("Name of Action Keybinding %d: %s\n", i, action_binding);
-
- if (!atk_action_set_description (action, i, desc))
- {
- g_print ("atk_action_set_description failed\n");
- }
- else
- {
- action_desc = atk_action_get_description (action, i);
- if (strcmp (desc, action_desc) != 0)
- {
- g_print ("Problem with setting and getting action description\n");
- }
- }
- }
- if (atk_action_set_description (action, n_actions, desc))
- {
- g_print ("atk_action_set_description succeeded but should not have\n");
- }
- }
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_object);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testaction Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <gtk/gtk.h>
-#include "testlib.h"
-
-/*
- * This module is used to test the accessible implementation for buttons
- *
- * 1) It verifies that ATK_STATE_ARMED is set when a button is pressed
- * To check this click on the button whose name is specified in the
- * environment variable TEST_ACCESSIBLE_NAME or "button box" if the
- * environment variable is not set.
- *
- * 2) If the environment variable TEST_ACCESSIBLE_AUTO is set the program
- * will execute the action defined for a GailButton once.
- *
- * 3) Change an inconsistent toggle button to be consistent and vice versa.
- *
- * Note that currently this code needs to be changed manually to test
- * different actions.
- */
-
-static void _create_event_watcher (void);
-static void _check_object (AtkObject *obj);
-static void button_pressed_handler (GtkButton *button);
-static void _print_states (AtkObject *obj);
-static void _print_button_image_info(AtkObject *obj);
-static gint _do_button_action (gpointer data);
-static gint _toggle_inconsistent (gpointer data);
-static gint _finish_button_action (gpointer data);
-
-#define NUM_VALID_ROLES 4
-
-static void
-_check_object (AtkObject *obj)
-{
- AtkRole role;
- static gboolean first_time = TRUE;
-
- role = atk_object_get_role (obj);
- if (role == ATK_ROLE_FRAME)
- /*
- * Find the specified button in the window
- */
- {
- AtkRole valid_roles[NUM_VALID_ROLES];
- const char *name;
- AtkObject *atk_button;
- GtkWidget *widget;
-
- valid_roles[0] = ATK_ROLE_PUSH_BUTTON;
- valid_roles[1] = ATK_ROLE_TOGGLE_BUTTON;
- valid_roles[2] = ATK_ROLE_CHECK_BOX;
- valid_roles[3] = ATK_ROLE_RADIO_BUTTON;
-
- name = g_getenv ("TEST_ACCESSIBLE_NAME");
- if (name == NULL)
- name = "button box";
- atk_button = find_object_by_accessible_name_and_role (obj, name,
- valid_roles, NUM_VALID_ROLES);
-
- if (atk_button == NULL)
- {
- g_print ("Object not found for %s\n", name);
- return;
- }
- g_assert (GTK_IS_ACCESSIBLE (atk_button));
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_button));
- g_assert (GTK_IS_BUTTON (widget));
- g_signal_connect (widget,
- "pressed",
- G_CALLBACK (button_pressed_handler),
- NULL);
- if (GTK_IS_TOGGLE_BUTTON (widget))
- {
- _toggle_inconsistent (GTK_TOGGLE_BUTTON (widget));
- }
- if (first_time)
- first_time = FALSE;
- else
- return;
-
- if (g_getenv ("TEST_ACCESSIBLE_AUTO"))
- {
- g_idle_add (_do_button_action, atk_button);
- }
- }
-}
-
-static gint _toggle_inconsistent (gpointer data)
-{
- GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (data);
-
- if (gtk_toggle_button_get_inconsistent (toggle_button))
- {
- gtk_toggle_button_set_inconsistent (toggle_button, FALSE);
- }
- else
- {
- gtk_toggle_button_set_inconsistent (toggle_button, TRUE);
- }
- return FALSE;
-}
-
-static gint _do_button_action (gpointer data)
-{
- AtkObject *obj = ATK_OBJECT (data);
-
- atk_action_do_action (ATK_ACTION (obj), 2);
-
- g_timeout_add (5000, _finish_button_action, obj);
- return FALSE;
-}
-
-static gint _finish_button_action (gpointer data)
-{
-#if 0
- AtkObject *obj = ATK_OBJECT (data);
-
- atk_action_do_action (ATK_ACTION (obj), 0);
-#endif
-
- return FALSE;
-}
-
-static void
-button_pressed_handler (GtkButton *button)
-{
- AtkObject *obj;
-
- obj = gtk_widget_get_accessible (GTK_WIDGET (button));
- _print_states (obj);
- _print_button_image_info (obj);
-
- if (GTK_IS_TOGGLE_BUTTON (button))
- {
- g_idle_add (_toggle_inconsistent, GTK_TOGGLE_BUTTON (button));
- }
-}
-
-static void
-_print_states (AtkObject *obj)
-{
- AtkStateSet *state_set;
- gint i;
-
- state_set = atk_object_ref_state_set (obj);
-
- g_print ("*** Start states ***\n");
- for (i = 0; i < 64; i++)
- {
- AtkStateType one_state;
- const gchar *name;
-
- if (atk_state_set_contains_state (state_set, i))
- {
- one_state = i;
-
- name = atk_state_type_get_name (one_state);
-
- if (name)
- g_print("%s\n", name);
- }
- }
- g_object_unref (state_set);
- g_print ("*** End states ***\n");
-}
-
-static void
-_print_button_image_info(AtkObject *obj) {
-
- gint height, width;
- const gchar *desc;
-
- height = width = 0;
-
- if(!ATK_IS_IMAGE(obj))
- return;
-
- g_print("*** Start Button Image Info ***\n");
- desc = atk_image_get_image_description(ATK_IMAGE(obj));
- g_print ("atk_image_get_image_desc returns : %s\n", desc ? desc : "<NULL>");
- atk_image_get_image_size(ATK_IMAGE(obj), &height ,&width);
- g_print("atk_image_get_image_size returns: height %d width %d\n",height,width);
- if(atk_image_set_image_description(ATK_IMAGE(obj), "New image Description")){
- desc = atk_image_get_image_description(ATK_IMAGE(obj));
- g_print ("atk_image_get_image_desc now returns : %s\n",desc ?desc:"<NULL>");
- }
- g_print("*** End Button Image Info ***\n");
-
-
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_object);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testbutton Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <gtk/gtk.h>
-#include "testlib.h"
-
-static void _test_selection (AtkObject *obj);
-static void _check_combo_box (AtkObject *obj);
-static void _check_children (AtkObject *obj);
-static gint _open_combo_list (gpointer data);
-static gint _close_combo_list (gpointer data);
-
-#define NUM_VALID_ROLES 1
-
-static void _check_children (AtkObject *obj)
-{
- gint n_children, i, j;
- AtkObject *child;
- AtkObject *grand_child;
-
- n_children = atk_object_get_n_accessible_children (obj);
-
- if (n_children > 1)
- {
- g_print ("*** Unexpected number of children for combo box: %d\n",
- n_children);
- return;
- }
- if (n_children == 2)
- {
- child = atk_object_ref_accessible_child (obj, 1);
- g_return_if_fail (atk_object_get_role (child) == ATK_ROLE_TEXT);
- j = atk_object_get_index_in_parent (child);
- if (j != 1)
- g_print ("*** inconsistency between parent and children %d %d ***\n",
- 1, j);
- g_object_unref (G_OBJECT (child));
- }
-
- child = atk_object_ref_accessible_child (obj, 0);
- g_return_if_fail (atk_object_get_role (child) == ATK_ROLE_LIST);
- j = atk_object_get_index_in_parent (child);
- if (j != 0)
- g_print ("*** inconsistency between parent and children %d %d ***\n",
- 0, j);
-
- n_children = atk_object_get_n_accessible_children (child);
- for (i = 0; i < n_children; i++)
- {
- const gchar *name;
-
- grand_child = atk_object_ref_accessible_child (child, i);
- name = atk_object_get_name (grand_child);
- g_print ("Index: %d Name: %s\n", i, name ? name : "<NULL>");
- g_object_unref (G_OBJECT (grand_child));
- }
- g_object_unref (G_OBJECT (child));
-}
-
-static void _test_selection (AtkObject *obj)
-{
- gint count;
- gint n_children;
- AtkObject *list;
-
- count = atk_selection_get_selection_count (ATK_SELECTION (obj));
- g_return_if_fail (count == 0);
-
- list = atk_object_ref_accessible_child (obj, 0);
- n_children = atk_object_get_n_accessible_children (list);
- g_object_unref (G_OBJECT (list));
-
- atk_selection_add_selection (ATK_SELECTION (obj), n_children - 1);
- count = atk_selection_get_selection_count (ATK_SELECTION (obj));
- g_return_if_fail (count == 1);
- g_return_if_fail (atk_selection_is_child_selected (ATK_SELECTION (obj),
- n_children - 1));
- atk_selection_add_selection (ATK_SELECTION (obj), 0);
- count = atk_selection_get_selection_count (ATK_SELECTION (obj));
- g_return_if_fail (count == 1);
- g_return_if_fail (atk_selection_is_child_selected (ATK_SELECTION (obj), 0));
- atk_selection_clear_selection (ATK_SELECTION (obj));
- count = atk_selection_get_selection_count (ATK_SELECTION (obj));
- g_return_if_fail (count == 0);
-}
-
-static void _check_combo_box (AtkObject *obj)
-{
- static gboolean done = FALSE;
- static gboolean done_selection = FALSE;
- AtkRole role;
-
- role = atk_object_get_role (obj);
-
- if (role == ATK_ROLE_FRAME)
- {
- AtkRole roles[NUM_VALID_ROLES];
- AtkObject *combo_obj;
-
- if (done_selection)
- return;
-
- roles[0] = ATK_ROLE_COMBO_BOX;
-
- combo_obj = find_object_by_role (obj, roles, NUM_VALID_ROLES);
-
- if (combo_obj)
- {
- if (!done_selection)
- {
- done_selection = TRUE;
- }
- if (g_getenv ("TEST_ACCESSIBLE_COMBO_NOEDIT") != NULL)
- {
- GtkWidget *combo;
- GtkEntry *entry;
-
- combo = gtk_accessible_get_widget (GTK_ACCESSIBLE (combo_obj));
- entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo)));
- gtk_editable_set_editable (GTK_EDITABLE (entry), FALSE);
- }
- _check_children (combo_obj);
- _test_selection (combo_obj);
- }
-
- return;
- }
- if (role != ATK_ROLE_COMBO_BOX)
- return;
-
- g_print ("*** Start ComboBox ***\n");
- _check_children (obj);
-
- if (!done)
- {
- g_idle_add ((GSourceFunc)_open_combo_list, obj);
- done = TRUE;
- }
- else
- return;
- g_print ("*** End ComboBox ***\n");
-}
-
-static gint _open_combo_list (gpointer data)
-{
- AtkObject *obj = ATK_OBJECT (data);
-
- g_print ("_open_combo_list\n");
- atk_action_do_action (ATK_ACTION (obj), 0);
-
- g_timeout_add (5000, _close_combo_list, obj);
- return FALSE;
-}
-
-static gint _close_combo_list (gpointer data)
-{
- AtkObject *obj = ATK_OBJECT (data);
-
- gint count;
- gint n_children;
- AtkObject *list;
-
- count = atk_selection_get_selection_count (ATK_SELECTION (obj));
- g_return_val_if_fail (count == 0, FALSE);
-
- list = atk_object_ref_accessible_child (obj, 0);
- n_children = atk_object_get_n_accessible_children (list);
- g_object_unref (G_OBJECT (list));
-
- atk_selection_add_selection (ATK_SELECTION (obj), n_children - 1);
-
- atk_action_do_action (ATK_ACTION (obj), 0);
-
- return FALSE;
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_combo_box);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testcombo Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <atk/atk.h>
-
-static void _check_position (AtkObject *obj);
-
-static void _check_position (AtkObject *obj)
-{
- AtkObject *parent, *ret_object;
-
- gint x, y, width, height;
- gint x1, y1, width1, height1;
-
- x = y = width = height = 0;
- x1 = y1 = width1 = height1 = 0;
-
- if (!ATK_IS_COMPONENT (obj))
- return;
-
- atk_component_get_extents (ATK_COMPONENT(obj), &x, &y, &width, &height, ATK_XY_SCREEN);
- atk_component_get_position (ATK_COMPONENT(obj), &x1, &y1, ATK_XY_SCREEN );
- atk_component_get_size (ATK_COMPONENT(obj), &width1, &height1);
- if ((x1 != x) || (y1 != y))
- {
- g_print ("atk_component_get_extents and atk_get_position give different"
- " values: %d,%d %d,%d\n", x, y, x1, y1);
- }
- if ((width1 != width) || (height1 != height))
- {
- g_print ("atk_component_get_extents and atk_get_size give different"
- " values: %d,%d %d,%d\n", width, height, width1, height1);
- }
-
- atk_component_get_position (ATK_COMPONENT(obj), &x1, &y1, ATK_XY_SCREEN);
- g_print ("Object Type: %s\n", g_type_name (G_OBJECT_TYPE (obj)));
- g_print ("Object at %d, %d on screen\n", x1, y1);
- g_print ("Object at %d, %d, size: %d, %d\n", x, y, width, height);
-
- parent = atk_object_get_parent (obj);
-
- if (ATK_IS_COMPONENT (parent))
- {
- gint px, py, pwidth, pheight;
-
- atk_component_get_extents (ATK_COMPONENT(parent),
- &px, &py, &pwidth, &pheight, ATK_XY_SCREEN);
- g_print ("Parent Type: %s\n", g_type_name (G_OBJECT_TYPE (parent)));
- g_print ("Parent at %d, %d, size: %d, %d\n", px, py, pwidth, pheight);
- ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
- x, y, ATK_XY_SCREEN);
-
- if (!ret_object)
- {
- g_print ("1:atk_component_ref_accessible_at_point returns NULL\n");
- }
- else if (ret_object != obj)
- {
- g_print ("1:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
- x, y);
- atk_component_get_extents (ATK_COMPONENT(ret_object),
- &px, &py, &pwidth, &pheight, ATK_XY_SCREEN);
- g_print ("ret_object at %d, %d, size: %d, %d\n", px, py, pwidth, pheight);
- }
- if (ret_object)
- g_object_unref (G_OBJECT (ret_object));
- ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
- x+width-1, y+height-1, ATK_XY_SCREEN);
- if (!ret_object)
- {
- g_print ("2:atk_component_ref_accessible_at_point returns NULL\n");
- }
- else if (ret_object != obj)
- {
- g_print ("2:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
- x+width-1, y+height-1);
- }
- if (ret_object)
- g_object_unref (G_OBJECT (ret_object));
- ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
- x-1, y-1, ATK_XY_SCREEN);
- if ((ret_object) && (ret_object == obj))
- {
- g_print ("3:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
- x-1, y-1);
- }
- if (ret_object)
- g_object_unref (G_OBJECT (ret_object));
- ret_object = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
- x+width, y+height, ATK_XY_SCREEN);
- if ((ret_object) && (ret_object == obj))
- {
- g_print ("4:atk_component_ref_accessible_at_point returns wrong value for %d %d\n",
- x+width, y+height);
- }
- if (ret_object)
- g_object_unref (G_OBJECT (ret_object));
- }
- if (!atk_component_contains (ATK_COMPONENT(obj), x, y, ATK_XY_SCREEN))
- g_print ("Component does not contain position, %d %d\n", x, y);
- if (atk_component_contains (ATK_COMPONENT(obj), x-1, y-1, ATK_XY_SCREEN))
- g_print ("Component does contain position, %d %d\n", x-1, y-1);
- if (!atk_component_contains (ATK_COMPONENT(obj), x+width-1, y+height-1, ATK_XY_SCREEN))
- g_print ("Component does not contain position, %d %d\n",
- x+width-1, y+height-1);
- if (atk_component_contains (ATK_COMPONENT(obj), x+width, y+height, ATK_XY_SCREEN))
- g_print ("Component does contain position, %d %d\n", x+width, y+height);
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_position);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testcomponent Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <gtk/gtk.h>
-#include "testlib.h"
-#include <stdlib.h>
-
-/*
- * This test modules tests the AtkImage interface. When the module is loaded
- * with testgtk , it also creates a dialog that contains GtkArrows and a
- * GtkImage.
- *
- */
-
-typedef struct
-{
- GtkWidget *dialog;
- GtkWidget *arrow1;
- GtkWidget *arrow2;
- GtkWidget *arrow3;
- GtkWidget *arrow4;
- GtkWidget *close_button;
- GtkImage *image;
-}MainDialog;
-
-static void destroy (GtkWidget *widget, gpointer data)
-{
- gtk_widget_destroy(GTK_WIDGET(data));
-}
-
-static void _check_arrows (AtkObject *obj)
-{
- GtkWidget *content_area, *action_area;
- AtkRole role;
- MainDialog *md;
- static gint visibleDialog = 0;
-
-
- role = atk_object_get_role(obj);
- if(role == ATK_ROLE_FRAME) {
-
- md = (MainDialog *) malloc (sizeof(MainDialog));
- if (visibleDialog == 0)
- {
- md->arrow1 = gtk_arrow_new(GTK_ARROW_UP,GTK_SHADOW_IN);
- md->arrow2 = gtk_arrow_new(GTK_ARROW_DOWN,GTK_SHADOW_IN);
- md->arrow3 = gtk_arrow_new(GTK_ARROW_LEFT,GTK_SHADOW_OUT);
- md->arrow4 = gtk_arrow_new(GTK_ARROW_RIGHT,GTK_SHADOW_OUT);
- md->dialog = gtk_dialog_new();
- gtk_window_set_modal(GTK_WINDOW(md->dialog), TRUE);
-
- content_area = gtk_dialog_get_content_area (GTK_DIALOG (md->dialog));
- action_area = gtk_dialog_get_action_area (GTK_DIALOG (md->dialog));
-
- gtk_box_pack_start(GTK_BOX (content_area), md->arrow1, TRUE,TRUE, 0);
- gtk_box_pack_start(GTK_BOX (content_area), md->arrow2, TRUE,TRUE, 0);
- gtk_box_pack_start(GTK_BOX (content_area), md->arrow3, TRUE,TRUE, 0);
- gtk_box_pack_start(GTK_BOX (content_area), md->arrow4, TRUE,TRUE, 0);
- g_signal_connect(md->dialog, "destroy",
- G_CALLBACK (destroy), md->dialog);
-
- md->image = GTK_IMAGE(gtk_image_new_from_file("circles.xbm"));
- gtk_box_pack_start(GTK_BOX (content_area), GTK_WIDGET(md->image), TRUE,TRUE, 0);
- md->close_button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
- g_signal_connect(md->close_button, "clicked",
- G_CALLBACK (destroy), md->dialog);
-
- gtk_box_pack_start(GTK_BOX (action_area), md->close_button, TRUE,TRUE, 0);
-
- gtk_widget_show_all(md->dialog);
- visibleDialog = 1;
- }
- }
-}
-
-
-static void
-_print_image_info(AtkObject *obj) {
-
- gint height, width;
- const gchar *desc;
- const gchar *name = atk_object_get_name (obj);
- const gchar *type_name = g_type_name(G_TYPE_FROM_INSTANCE (obj));
-
- height = width = 0;
-
-
- if(!ATK_IS_IMAGE(obj))
- return;
-
- g_print("atk_object_get_name : %s\n", name ? name : "<NULL>");
- g_print("atk_object_get_type_name : %s\n",type_name ?type_name :"<NULL>");
- g_print("*** Start Image Info ***\n");
- desc = atk_image_get_image_description(ATK_IMAGE(obj));
- g_print ("atk_image_get_image_desc returns : %s\n",desc ? desc:"<NULL>");
- atk_image_get_image_size(ATK_IMAGE(obj), &height ,&width);
- g_print("atk_image_get_image_size returns: height %d width %d\n",
- height,width);
- if(atk_image_set_image_description(ATK_IMAGE(obj),"New image Description")){
- desc = atk_image_get_image_description(ATK_IMAGE(obj));
- g_print ("atk_image_get_image_desc now returns : %s\n",desc?desc:"<NULL>");
- }
- g_print("*** End Image Info ***\n");
-
-
-}
-static void _traverse_children (AtkObject *obj)
-{
- gint n_children, i;
-
- n_children = atk_object_get_n_accessible_children (obj);
- for (i = 0; i < n_children; i++)
- {
- AtkObject *child;
-
- child = atk_object_ref_accessible_child (obj, i);
- _print_image_info(child);
- _traverse_children (child);
- g_object_unref (G_OBJECT (child));
- }
-}
-
-
-static void _check_objects (AtkObject *obj)
-{
- AtkRole role;
-
- g_print ("Start of _check_values\n");
-
- _check_arrows(obj);
- role = atk_object_get_role (obj);
-
- if (role == ATK_ROLE_FRAME || role == ATK_ROLE_DIALOG)
- {
- /*
- * Add handlers to all children.
- */
- _traverse_children (obj);
- }
- g_print ("End of _check_values\n");
-}
-
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_objects);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testimages Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "testlib.h"
-
-static gint _get_position_in_array (gint window,
- gchar *the_test_name);
-static gint _get_position_in_parameters (gint window,
- gchar *label,
- gint position);
-static void _create_output_window (OutputWindow **outwin);
-static gboolean _create_select_tests_window (AtkObject *obj,
- TLruntest runtest,
- OutputWindow **outwin);
-static void _toggle_selectedcb (GtkWidget *widget,
- gpointer test);
-static void _testselectioncb (GtkWidget *widget,
- gpointer data);
-static void _destroy (GtkWidget *widget,
- gpointer data);
-
-/* General functions */
-
-/**
- * find_object_by_role:
- * @obj: An #AtkObject
- * @roles: An array of roles to search for
- * @num_roles: The number of entries in @roles
- *
- * Find the #AtkObject which is a decendant of the specified @obj
- * which is of an #AtkRole type specified in the @roles array.
- *
- * Returns: the #AtkObject that meets the specified criteria or NULL
- * if no object is found.
- **/
-AtkObject*
-find_object_by_role (AtkObject *obj,
- AtkRole *roles,
- gint num_roles)
-{
- /*
- * Find the first object which is a descendant of the specified object
- * which matches the specified role.
- *
- * This function returns a reference to the AtkObject which should be
- * removed when finished with the object.
- */
- gint i, j;
- gint n_children;
- AtkObject *child;
-
- if (obj == NULL)
- return NULL;
-
- for (j=0; j < num_roles; j++)
- {
- if (atk_object_get_role (obj) == roles[j])
- return obj;
- }
-
- n_children = atk_object_get_n_accessible_children (obj);
- for (i = 0; i < n_children; i++)
- {
- AtkObject* found_obj;
-
- child = atk_object_ref_accessible_child (obj, i);
-
- if (child == NULL)
- continue;
-
- for (j=0; j < num_roles; j++)
- {
- if (atk_object_get_role (child) == roles[j])
- return child;
- }
-
- found_obj = find_object_by_role (child, roles, num_roles);
- g_object_unref (child);
- if (found_obj)
- return found_obj;
- }
- return NULL;
-}
-
-/**
- * find_object_by_name_and_role:
- * @obj: An #AtkObject
- * @name: The GTK widget name
- * @roles: An array of roles to search for
- * @num_roles: The number of entries in @roles
- *
- * Find the #AtkObject which is a decendant of the specified @obj
- * which is of an #AtkRole type specified in the @roles array which
- * also has the GTK widget name specified in @name.
- *
- * Returns: the #AtkObject that meets the specified criteria or NULL
- * if no object is found.
- **/
-AtkObject*
-find_object_by_name_and_role(AtkObject *obj,
- const gchar *name,
- AtkRole *roles,
- gint num_roles)
-{
- AtkObject *child;
- GtkWidget* widget;
- gint i, j;
- gint n_children;
-
- if (obj == NULL)
- return NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- if (GTK_IS_WIDGET (widget))
- {
- if (strcmp (name, gtk_widget_get_name(GTK_WIDGET (widget))) == 0)
- {
- for (j=0; j < num_roles; j++)
- {
- if (atk_object_get_role (obj) == roles[j])
- return obj;
- }
- }
- }
-
- n_children = atk_object_get_n_accessible_children (obj);
- for (i = 0; i < n_children; i++)
- {
- AtkObject* found_obj;
-
- child = atk_object_ref_accessible_child (obj, i);
-
- if (child == NULL)
- continue;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (child));
- if (GTK_IS_WIDGET (widget))
- {
- if (strcmp(name, gtk_widget_get_name(GTK_WIDGET (widget))) == 0)
- {
- for (j=0; j < num_roles; j++)
- {
- if (atk_object_get_role (child) == roles[j])
- return child;
- }
- }
- }
- found_obj = find_object_by_name_and_role (child, name, roles, num_roles);
- g_object_unref (child);
- if (found_obj)
- return found_obj;
- }
- return NULL;
-}
-
-/**
- * find_object_by_accessible_name_and_role:
- * @obj: An #AtkObject
- * @name: The accessible name
- * @roles: An array of roles to search for
- * @num_roles: The number of entries in @roles
- *
- * Find the #AtkObject which is a decendant of the specified @obj
- * which has the specified @name and matches one of the
- * specified @roles.
- *
- * Returns: the #AtkObject that meets the specified criteria or NULL
- * if no object is found.
- */
-AtkObject*
-find_object_by_accessible_name_and_role (AtkObject *obj,
- const gchar *name,
- AtkRole *roles,
- gint num_roles)
-{
- AtkObject *child;
- gint i, j;
- gint n_children;
- const gchar *accessible_name;
-
- if (obj == NULL)
- return NULL;
-
- accessible_name = atk_object_get_name (obj);
- if (accessible_name && (strcmp(name, accessible_name) == 0))
- {
- for (j=0; j < num_roles; j++)
- {
- if (atk_object_get_role (obj) == roles[j])
- return obj;
- }
- }
-
- n_children = atk_object_get_n_accessible_children (obj);
- for (i = 0; i < n_children; i++)
- {
- AtkObject* found_obj;
-
- child = atk_object_ref_accessible_child (obj, i);
-
- if (child == NULL)
- continue;
-
- accessible_name = atk_object_get_name (child);
- if (accessible_name && (strcmp(name, accessible_name) == 0))
- {
- for (j=0; j < num_roles; j++)
- {
- if (atk_object_get_role (child) == roles[j])
- return child;
- }
- }
- found_obj = find_object_by_accessible_name_and_role (child, name,
- roles, num_roles);
- g_object_unref (child);
- if (found_obj)
- return found_obj;
- }
- return NULL;
-}
-
-/**
- * find_object_by_name_and_role:
- * @obj: An #AtkObject
- * @type: The type
- *
- * Find the #AtkObject which is a decendant of the specified @obj
- * which has the specified @type.
- *
- * Returns: the #AtkObject that meets the specified criteria or NULL
- * if no object is found.
- */
-AtkObject*
-find_object_by_type (AtkObject *obj,
- gchar *type)
-{
- /*
- * Find the first object which is a descendant of the specified object
- * which matches the specified type.
- *
- * This function returns a reference to the AtkObject which should be
- * removed when finished with the object.
- */
- gint i;
- gint n_children;
- AtkObject *child;
- const gchar * typename = NULL;
-
- if (obj == NULL)
- return NULL;
-
- typename = g_type_name (G_OBJECT_TYPE (obj));
- if (strcmp (typename, type) == 0)
- return obj;
-
- n_children = atk_object_get_n_accessible_children (obj);
- for (i = 0; i < n_children; i++)
- {
- AtkObject* found_obj;
-
- child = atk_object_ref_accessible_child (obj, i);
-
- if (child == NULL)
- continue;
-
- typename = g_type_name (G_OBJECT_TYPE (child));
-
- if (strcmp (typename, type) == 0)
- return child;
-
- found_obj = find_object_by_type (child, type);
- g_object_unref (child);
- if (found_obj)
- return found_obj;
- }
- return NULL;
-}
-
-/**
- * already_accessed_atk_object
- * @obj: An #AtkObject
- *
- * Keeps a static GPtrArray of objects that have been passed into this
- * function.
- *
- * Returns: TRUE if @obj has been passed into this function before
- * and FALSE otherwise.
- */
-gboolean
-already_accessed_atk_object (AtkObject *obj)
-{
- static GPtrArray *obj_array = NULL;
- gboolean found = FALSE;
- gint i;
-
- /*
- * We create a property handler for each object if one was not associated
- * with it already.
- *
- * We add it to our array of objects which have property handlers; if an
- * object is destroyed it remains in the array.
- */
- if (obj_array == NULL)
- obj_array = g_ptr_array_new ();
-
- for (i = 0; i < obj_array->len; i++)
- {
- if (obj == g_ptr_array_index (obj_array, i))
- {
- found = TRUE;
- break;
- }
- }
- if (!found)
- g_ptr_array_add (obj_array, obj);
-
- return found;
-}
-
-/**
- * display_children
- * @obj: An #AtkObject
- * @depth: Number of spaces to indent output.
- * @child_number: The child number of this object.
- *
- * Displays the hierarchy of widgets starting from @obj.
- **/
-void
-display_children (AtkObject *obj,
- gint depth,
- gint child_number)
-{
- display_children_to_depth(obj, -1, depth, child_number);
-}
-
-/**
- * display_children_to_depth
- * @obj: An #AtkObject
- * @to_depth: Display to this depth.
- * @depth: Number of spaces to indent output.
- * @child_number: The child number of this object.
- *
- * Displays the hierarchy of widgets starting from @obj only
- * to the specified depth.
- **/
-void
-display_children_to_depth (AtkObject *obj,
- gint to_depth,
- gint depth,
- gint child_number)
-{
- AtkRole role;
- const gchar *rolename;
- const gchar *typename;
- gint n_children, parent_index, i;
-
- if (to_depth >= 0 && depth > to_depth)
- return;
-
- if (obj == NULL)
- return;
-
- for (i=0; i < depth; i++)
- g_print(" ");
-
- role = atk_object_get_role (obj);
- rolename = atk_role_get_name (role);
-
- /*
- * Note that child_number and parent_index should be the same
- * unless there is an error.
- */
- parent_index = atk_object_get_index_in_parent(obj);
- g_print("child <%d == %d> ", child_number, parent_index);
-
- n_children = atk_object_get_n_accessible_children (obj);
- g_print ("children <%d> ", n_children);
-
- if (rolename)
- g_print("role <%s>, ", rolename);
- else
- g_print("role <error>");
-
- if (GTK_IS_ACCESSIBLE(obj))
- {
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- g_print("name <%s>, ", gtk_widget_get_name(GTK_WIDGET (widget)));
- }
- else
- g_print("name <NULL>, ");
-
- typename = g_type_name (G_OBJECT_TYPE (obj));
- g_print ("typename <%s>\n", typename);
-
- for (i = 0; i < n_children; i++)
- {
- AtkObject *child;
-
- child = atk_object_ref_accessible_child (obj, i);
- if (child != NULL)
- {
- display_children_to_depth (child, to_depth, depth + 1, i);
- g_object_unref (G_OBJECT (child));
- }
- }
-}
-
-/* Test GUI logic */
-
-/* GUI Information for the Select Tests Window */
-typedef struct
-{
- GtkWidget *selecttestsWindow;
- GtkWidget *hbox;
- GtkWidget *vbox;
- GtkWidget *label;
- GtkWidget *textInsert;
- GtkWidget *button;
- gchar *selecttestsTitle;
-}MainDialog;
-
-/* Functionality information about each added test */
-typedef struct
-{
- GtkWidget *toggleButton;
- GtkWidget *hbox;
- GtkWidget *parameterLabel[MAX_PARAMS];
- GtkWidget *parameterInput[MAX_PARAMS];
- gchar *testName;
- gint numParameters;
-}TestList;
-
-typedef struct
-{
- TLruntest runtest;
- AtkObject* obj;
- gint win_num;
-}TestCB;
-
-static MainDialog *md[MAX_WINDOWS];
-static OutputWindow *ow;
-
-/* An array containing function information on all of the tests */
-static TestList listoftests[MAX_WINDOWS][MAX_TESTS];
-
-/* A counter for the actual number of added tests */
-gint counter;
-
-/* A global for keeping track of the window numbers */
-static gint window_no = 0;
-/* An array containing the names of the tests that are "on" */
-static gchar *onTests[MAX_WINDOWS][MAX_TESTS];
-static gint g_visibleDialog = 0;
-static gint testcount[MAX_WINDOWS];
-static TestCB testcb[MAX_WINDOWS];
-
-/**
- * create_windows:
- * @obj: An #AtkObject
- * @runtest: The callback function to run when the "Run Tests" button
- * is clicked.
- * @outwin: The output window to use. If NULL is passed in, then
- * create a new one.
- *
- * Creates the test window and the output window (if @outwin is NULL)
- * Runs _create_output_window() and _create_select_tests_window()
- * and sets g_visibleDialog to 1
- *
- * Returns: The window number of the created window if successful, -1 otherwise.
- **/
-gint
-create_windows (AtkObject *obj,
- TLruntest runtest,
- OutputWindow **outwin)
-{
- gboolean valid;
- gint tmp;
-
- g_visibleDialog = 1;
- _create_output_window(outwin);
- valid = _create_select_tests_window(obj, runtest, outwin);
- if (valid)
- {
- tmp = window_no;
- window_no++;
- return tmp;
- }
- else
- return -1;
-}
-
-/**
- * _create_output_window
- * @outwin: If outwin is passed in as NULL, a new output window is created
- * otherwise, the outwin passed in is shared.
- *
- * Creates the Test Result Output Window .
- **/
-static void
-_create_output_window (OutputWindow **outwin)
-{
- GtkWidget *view;
- GtkWidget *scrolled_window;
- OutputWindow *localow;
-
- if (*outwin == NULL)
- {
- localow = (OutputWindow *) malloc (sizeof(OutputWindow));
-
- localow->outputBuffer = gtk_text_buffer_new(NULL);
- view = gtk_text_view_new_with_buffer(GTK_TEXT_BUFFER(localow->outputBuffer));
- gtk_widget_set_size_request (view, 700, 500);
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD);
- gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);
-
- localow->outputWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(localow->outputWindow), "Test Output");
- scrolled_window = gtk_scrolled_window_new(NULL, NULL);
-
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_container_add(GTK_CONTAINER(localow->outputWindow), scrolled_window);
- gtk_container_add(GTK_CONTAINER(scrolled_window), view);
- gtk_text_buffer_get_iter_at_offset(localow->outputBuffer, &localow->outputIter, 0);
- gtk_widget_show(view);
- gtk_widget_show(scrolled_window);
- gtk_widget_show(localow->outputWindow);
-
- gtk_text_buffer_set_text(GTK_TEXT_BUFFER(localow->outputBuffer),
- "\n\nWelcome to the test GUI:\nTest results are printed here\n\n", 58);
- gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(localow->outputBuffer),
- &localow->outputIter, 0);
- *outwin = localow;
- ow = *outwin;
- }
-}
-
-/**
- * _create_select_tests_window:
- * @obj: An #AtkObject
- * @runtest: The callback function that is run when the "Run Tests"
- * button is clicked.
- * @outwin: The output window to use.
- *
- * Creates the Test Select Window
- *
- * Returns: TRUE if successful, FALSE otherwise
- **/
-static gboolean
-_create_select_tests_window (AtkObject *obj,
- TLruntest runtest,
- OutputWindow **outwin)
-{
- GtkWidget *hbuttonbox;
- GtkWidget *scrolledWindow;
-
- if (window_no >= 0 && window_no < MAX_WINDOWS)
- {
- md[window_no] = (MainDialog *) malloc (sizeof(MainDialog));
-
- /* Setup Window */
- md[window_no]->selecttestsTitle = "Test Setting";
- md[window_no]->selecttestsWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW( ow->outputWindow),
- md[window_no]->selecttestsTitle);
- gtk_window_set_resizable (GTK_WINDOW(md[window_no]->selecttestsWindow),
- FALSE);
- gtk_window_set_position (GTK_WINDOW(md[window_no]->selecttestsWindow),
- GTK_WIN_POS_CENTER);
- g_signal_connect (md[window_no]->selecttestsWindow,
- "destroy",
- G_CALLBACK (_destroy),
- &md[window_no]->selecttestsWindow);
-
- /* Setup Scrolling */
- scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledWindow),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_widget_set_size_request (scrolledWindow, 500, 600);
- gtk_container_add (GTK_CONTAINER (md[window_no]->selecttestsWindow),
- scrolledWindow);
-
- /* Setup Layout */
- md[window_no]->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_box_set_homogeneous (GTK_BOX (md[window_no]->vbox), TRUE);
- md[window_no]->button = gtk_button_new_with_mnemonic ("_Run Tests");
- hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox),
- GTK_BUTTONBOX_SPREAD);
- gtk_box_pack_end (GTK_BOX (hbuttonbox),
- GTK_WIDGET (md[window_no]->button), TRUE, TRUE, 0);
- gtk_box_pack_end (GTK_BOX (md[window_no]->vbox), hbuttonbox,
- TRUE, TRUE, 0);
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolledWindow),
- md[window_no]->vbox);
-
- testcb[window_no].runtest = runtest;
- testcb[window_no].obj = obj;
- testcb[window_no].win_num = window_no;
- g_signal_connect (md[window_no]->button,
- "clicked",
- G_CALLBACK (_testselectioncb),
- (gpointer)&testcb[window_no]);
-
- /* Show all */
- gtk_widget_grab_focus (md[window_no]->button);
- gtk_widget_show (md[window_no]->button);
- gtk_widget_show (hbuttonbox);
- gtk_widget_show (scrolledWindow);
- gtk_widget_show_all (GTK_WIDGET (md[window_no]->selecttestsWindow));
- return TRUE;
- }
- else
- return FALSE;
-}
-
-/**
- * add_test
- * @window: The window number
- * @name: The test name
- * @num_params: The number of arguments the test uses.
- * @parameter_names: The names of each argument.
- * @default_names: The default values of each argument.
- *
- * Adds a Test with the passed-in details to the Tests Select Window.
- *
- * Returns: FALSE if the num_params passed in is greater than
- * MAX_PARAMS, otherwise returns TRUE
- *
- **/
-gboolean
-add_test (gint window,
- gchar *name,
- gint num_params,
- gchar* parameter_names[],
- gchar* default_names[])
-{
- gint i;
-
- if (num_params > MAX_PARAMS)
- return FALSE;
- else
- {
- md[window]->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_set_spacing (GTK_BOX (md[window]->hbox), 10);
- gtk_container_set_border_width (GTK_CONTAINER (md[window]->hbox), 10);
- gtk_container_add (GTK_CONTAINER (md[window]->vbox), md[window]->hbox);
- listoftests[window][testcount[window]].toggleButton =
- gtk_toggle_button_new_with_label (name);
- gtk_box_pack_start (GTK_BOX (md[window]->hbox),
- listoftests[window][testcount[window]].toggleButton, FALSE, FALSE, 0);
- listoftests[window][testcount[window]].testName = name;
- listoftests[window][testcount[window]].numParameters = num_params;
- for (i=0; i<num_params; i++)
- {
- listoftests[window][testcount[window]].parameterLabel[i] =
- gtk_label_new (parameter_names[i]);
- gtk_box_pack_start (GTK_BOX (md[window]->hbox),
- listoftests[window][testcount[window]].parameterLabel[i], FALSE, FALSE, 0);
- listoftests[window][testcount[window]].parameterInput[i] = gtk_entry_new();
- gtk_entry_set_text (GTK_ENTRY (listoftests[window][testcount[window]].parameterInput[i]),
- default_names[i]);
- gtk_widget_set_size_request (listoftests[window][testcount[window]].parameterInput[i], 50, 22);
- gtk_box_pack_start (GTK_BOX (md[window]->hbox),
- listoftests[window][testcount[window]].parameterInput[i], FALSE, FALSE, 0);
- gtk_widget_set_sensitive (
- GTK_WIDGET (listoftests[window][testcount[window]].parameterLabel[i]), FALSE);
- gtk_widget_set_sensitive (
- GTK_WIDGET (listoftests[window][testcount[window]].parameterInput[i]), FALSE);
- gtk_widget_show (listoftests[window][testcount[window]].parameterLabel[i]);
- gtk_widget_show (listoftests[window][testcount[window]].parameterInput[i]);
- }
- g_signal_connect (listoftests[window][testcount[window]].toggleButton,
- "toggled",
- G_CALLBACK (_toggle_selectedcb),
- (gpointer)&(listoftests[window][testcount[window]]));
- gtk_widget_show (listoftests[window][testcount[window]].toggleButton);
- gtk_widget_show (md[window]->hbox);
- gtk_widget_show (md[window]->vbox);
-
- testcount[window]++;
- counter++;
- return TRUE;
- }
-}
-
-/**
- * tests_set:
- * @window: The window number
- * @count: Passes back the number of tests on.
- *
- * Gets an array of strings corresponding to the tests that are "on".
- * A test is assumed on if the toggle button is on and if all its
- * parameters have values.
- *
- * Returns: an array of strings corresponding to the tests that
- * are "on".
- **/
-gchar **tests_set(gint window, int *count)
-{
- gint i =0, j = 0, num;
- gboolean nullparam;
- gchar* input;
-
- *count = 0;
- for (i = 0; i < MAX_TESTS; i++)
- onTests[window][i] = NULL;
-
- for (i = 0; i < testcount[window]; i++)
- {
- nullparam = FALSE;
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (listoftests[window][i].toggleButton)))
- {
- num = listoftests[window][i].numParameters;
- for (j = 0; j < num; j++)
- {
- input = gtk_editable_get_chars (
- GTK_EDITABLE (listoftests[window][i].parameterInput[j]), 0, -1);
-
- if (input != NULL && (! strcmp(input, "")))
- nullparam = TRUE;
- }
- if (!nullparam)
- {
- onTests[window][*count] = listoftests[window][i].testName;
- *count = *count + 1;
- }
- }
- }
- return onTests[window];
-}
-
-/**
- * _get_position_in_array:
- * @window: The window number
- * @the_test_name: The name of the test
- *
- * Gets the index of the passed-in @the_test_name.
- *
- * Returns: the position in listoftests[] of @the_test_name
- **/
-static gint
-_get_position_in_array(gint window,
- gchar *the_test_name)
-{
- gint i;
-
- for (i = 0; i < testcount[window]; i++)
- {
- if (strcmp(listoftests[window][i].testName, the_test_name) == 0)
- return i;
- }
- return -1;
-}
-
-/**
- * _get_position_in_parameters:
- * @window: The window number
- * @label: The label name
- * @position: The parameter position
- *
- * Gets the index of the passed-in parameter @label.
- *
- * Returns: the position in parameterLabel[] (a member of
- * listoftests[]) of @label
- **/
-static gint
-_get_position_in_parameters(gint window,
- gchar *label,
- gint position)
-{
- gint i;
- const gchar *label_string;
-
- for (i = 0; i < MAX_PARAMS; i++)
- {
- label_string = gtk_label_get_text(
- GTK_LABEL (listoftests[window][position].parameterLabel[i]));
-
- if (strcmp(label_string, label) == 0)
- return i;
- }
- return -1;
-}
-
-/**
- * set_output_buffer:
- * @output: The string to add to the output buffer
- *
- * Tidies up the output Window
- **/
-void
-set_output_buffer(gchar *output)
-{
- gtk_text_buffer_insert (GTK_TEXT_BUFFER (ow->outputBuffer),
- &ow->outputIter, output, strlen(output));
- gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (ow->outputBuffer),
- &ow->outputIter, 0);
-}
-
-/**
- * isVisibleDialog:
- *
- * Informs user if a visible test window running.
- *
- * Returns: TRUE if g_visibleDialog is set to 1, otherwise FALSE
- **/
-gboolean
-isVisibleDialog(void)
-{
- if (g_visibleDialog >= 1)
- return TRUE;
- else
- return FALSE;
-}
-
-/**
- * get_arg_of_func:
- * @window: The window number
- * @function_name: The name of the function
- * @arg_label: The label of the argument.
- *
- * Gets the user input associated with the @function_name and @arg_label.
- *
- * Returns: the user input associated with the @function_name and @arg_label.
- **/
-gchar*
-get_arg_of_func (gint window,
- gchar *function_name,
- gchar *arg_label)
-{
- const gchar *argString;
- gchar *retString;
- gint position, paramPosition;
-
- position = _get_position_in_array(window, function_name);
-
- if (position == -1)
- {
- g_print("No such function\n");
- return NULL;
- }
-
- paramPosition = _get_position_in_parameters(window, arg_label, position);
-
- if (paramPosition == -1)
- {
- g_print("No such parameter Label\n");
- return NULL;
- }
-
- if (position != -1 && paramPosition != -1)
- {
- argString = gtk_editable_get_chars (
- GTK_EDITABLE (listoftests[window][position].parameterInput[paramPosition]),
- 0, -1);
- retString = g_strdup(argString);
- }
- else
- retString = NULL;
-
- return retString;
-}
-
-/**
- * string_to_int:
- * @the_string: The string to convert
- *
- * Converts the passed-in string to an integer
- *
- * Returns: An integer corresponding to @the_string.
- **/
-int
-string_to_int (const char *the_string)
-{
- char *end_ptr;
- double ret_val;
- int int_ret_val;
-
- while (1)
- {
- ret_val = strtod( the_string, &end_ptr);
- if (*end_ptr == '\0')
- break;
- else
- printf("\nError: input must be a number\n");
- }
-
- int_ret_val = (int) ret_val;
- return (int_ret_val);
-}
-
-/**
- * _toggle_selectedcb:
- * @widget: The ToggleButton widget
- * @test: user data containing the TestList structure.
- *
- * Toggle Button Callback, activating the text entry fields
- **/
-static void
-_toggle_selectedcb (GtkWidget *widget,
- gpointer test)
-{
- int i;
- TestList *testlist = (TestList *) test;
- gboolean toggled;
- gboolean sensitive;
- toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
- if (toggled)
- sensitive = TRUE;
- else
- sensitive = FALSE;
-
- for (i=0; i < testlist->numParameters; i++)
- {
- gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterLabel[i]),
- sensitive);
- gtk_widget_set_sensitive (GTK_WIDGET (testlist->parameterInput[i]),
- sensitive);
- }
-}
-
-/*
- * _testselectioncb:
- * widget: The Button widget
- * data: The user data containing a TestCB structure
- *
- * Callback for when the "Run Tests" button is pressed
- **/
-static void
-_testselectioncb (GtkWidget *widget,
- gpointer data)
-{
- TestCB* local_testcb = (TestCB *)data;
- local_testcb->runtest(local_testcb->obj, local_testcb->win_num);
-}
-
-/**
- * _destroy:
- * @widget: The GUI widget
- * @data: User data, not used.
- *
- * Destroy Callback.
- **/
-static void
-_destroy (GtkWidget *widget,
- gpointer data)
-{
- gtk_main_quit();
-}
-
+++ /dev/null
-#include <stdio.h>
-#include <gtk/gtk.h>
-
-/* Maximum characters in the output buffer */
-#define MAX_LINE_SIZE 1000
-
-/* Maximum number of tests */
-#define MAX_TESTS 30
-
-/* Maximum number of test windows */
-#define MAX_WINDOWS 5
-
-/* Maximum number of parameters any test can have */
-#define MAX_PARAMS 3
-
-/* Information on the Output Window */
-
-typedef struct
-{
- GtkWidget *outputWindow;
- GtkTextBuffer *outputBuffer;
- GtkTextIter outputIter;
-}OutputWindow;
-
-typedef void (*TLruntest) (AtkObject * obj, gint win_num);
-
-/* General purpose functions */
-
-gboolean already_accessed_atk_object (AtkObject *obj);
-AtkObject* find_object_by_role (AtkObject *obj,
- AtkRole *role,
- gint num_roles);
-AtkObject* find_object_by_type (AtkObject *obj,
- gchar *type);
-AtkObject* find_object_by_name_and_role (AtkObject *obj,
- const gchar *name,
- AtkRole *roles,
- gint num_roles);
-AtkObject* find_object_by_accessible_name_and_role (AtkObject *obj,
- const gchar *name,
- AtkRole *roles,
- gint num_roles);
-void display_children (AtkObject *obj,
- gint depth,
- gint child_number);
-void display_children_to_depth (AtkObject *obj,
- gint to_depth,
- gint depth,
- gint child_number);
-
-
-/* Test GUI functions */
-
-gint create_windows (AtkObject *obj,
- TLruntest runtest,
- OutputWindow **outwin);
-gboolean add_test (gint window,
- gchar *name,
- gint num_params,
- gchar *parameter_names[],
- gchar *default_names[]);
-void set_output_buffer (gchar *output);
-gchar **tests_set (gint window,
- int *count);
-gchar *get_arg_of_func (gint window,
- gchar *function_name,
- gchar *arg_label);
-int string_to_int (const char *the_string);
-gboolean isVisibleDialog (void);
-
+++ /dev/null
-#include <string.h>
-#include <gtk/gtk.h>
-#include "testlib.h"
-
-/*
- * This module is used to test the accessible implementation for menu items
- *
- * 1) When a menu item is clicked in testgtk, the action for the
- * item is performed.
- * 2) The name of the keybinding for the 'activate" action for a menu item
- * is output, if it exists.
- * 3) Execute the action for a menu item programatically
- */
-#define NUM_VALID_ROLES 1
-
-static void _create_event_watcher (void);
-static void _check_object (AtkObject *obj);
-static gint _do_menu_item_action (gpointer data);
-
-static void
-_check_object (AtkObject *obj)
-{
- AtkRole role;
- static const char *name = NULL;
- static gboolean first_time = TRUE;
-
- role = atk_object_get_role (obj);
- if (role == ATK_ROLE_FRAME)
- /*
- * Find the specified menu item
- */
- {
- AtkRole valid_roles[NUM_VALID_ROLES];
- AtkObject *atk_menu_item;
- GtkWidget *widget;
-
- if (name == NULL)
- {
- valid_roles[0] = ATK_ROLE_MENU_ITEM;
-
- name = g_getenv ("TEST_ACCESSIBLE_NAME");
- if (name == NULL)
- name = "foo";
- }
- atk_menu_item = find_object_by_accessible_name_and_role (obj, name,
- valid_roles, NUM_VALID_ROLES);
-
- if (atk_menu_item == NULL)
- {
- g_print ("Object not found for %s\n", name);
- return;
- }
-
- g_assert (GTK_IS_ACCESSIBLE (atk_menu_item));
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_menu_item));
- g_assert (GTK_IS_MENU_ITEM (widget));
-
- if (first_time)
- first_time = FALSE;
- else
- return;
-
- /*
- * This action opens the menu whose name is "foo" or whatever
- * was specified in the environment variable TEST_ACCESSIBLE_NAME
- */
- atk_action_do_action (ATK_ACTION (atk_menu_item), 0);
- }
- else if ((role == ATK_ROLE_MENU_ITEM) ||
- (role == ATK_ROLE_CHECK_MENU_ITEM) ||
- (role == ATK_ROLE_RADIO_MENU_ITEM) ||
- (role == ATK_ROLE_TEAR_OFF_MENU_ITEM))
- {
- const char *keybinding;
- const char *accessible_name;
-
- accessible_name = atk_object_get_name (obj);
- if (accessible_name)
- g_print ("Name: %s\n", accessible_name);
- g_print ("Action: %s\n", atk_action_get_name (ATK_ACTION (obj), 0));
- keybinding = atk_action_get_keybinding (ATK_ACTION (obj), 0);
- if (keybinding)
- g_print ("KeyBinding: %s\n", keybinding);
- /*
- * Do the action associated with the menu item once, otherwise
- * we get into a loop
- */
- if (strcmp (name, accessible_name) == 0)
- {
- if (first_time)
- first_time = FALSE;
- else
- return;
- if (g_getenv ("TEST_ACCESSIBLE_AUTO"))
- {
- g_idle_add (_do_menu_item_action, obj);
- }
- }
- }
- else
- {
- const char *accessible_name;
-
- accessible_name = atk_object_get_name (obj);
- if (accessible_name)
- g_print ("Name: %s\n", accessible_name);
- else if (GTK_IS_ACCESSIBLE (obj))
- {
- GtkWidget *widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- g_print ("Type: %s\n", g_type_name (G_OBJECT_TYPE (widget)));
- }
- }
-}
-
-static gint _do_menu_item_action (gpointer data)
-{
- AtkObject *obj = ATK_OBJECT (data);
-
- atk_action_do_action (ATK_ACTION (obj), 0);
-
- return FALSE;
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_object);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testmenuitem Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <stdio.h>
-
-#include <glib.h>
-#include <atk/atk.h>
-#include <gtk/gtk.h>
-#include "testlib.h"
-
-#define NUM_VALID_ROLES 1
-
-static void _print_type (AtkObject *obj);
-static void _do_selection (AtkObject *obj);
-static gint _finish_selection (gpointer data);
-static gint _remove_page (gpointer data);
-
-static void _print_type (AtkObject *obj)
-{
- const gchar *typename = NULL;
- const gchar *name = NULL;
- const gchar *description = NULL;
- AtkRole role;
-
- if (GTK_IS_ACCESSIBLE (obj))
- {
- GtkWidget* widget = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- typename = g_type_name (G_OBJECT_TYPE (widget));
- g_print ("\tWidget type name: %s\n", typename ? typename : "NULL");
- }
-
- typename = g_type_name (G_OBJECT_TYPE (obj));
- g_print ("\tAccessible type name: %s\n", typename ? typename : "NULL");
-
- name = atk_object_get_name (obj);
- g_print("\tAccessible Name: %s\n", (name) ? name : "NULL");
-
- role = atk_object_get_role(obj);
- g_print ("\tAccessible Role: %d\n", role);
-
- description = atk_object_get_description (obj);
- g_print ("\tAccessible Description: %s\n", (description) ? description : "NULL");
- if (role == ATK_ROLE_PAGE_TAB)
- {
- AtkObject *parent, *child;
- gint x, y, width, height;
-
- x = y = width = height = 0;
- atk_component_get_extents (ATK_COMPONENT (obj), &x, &y, &width, &height,
- ATK_XY_SCREEN);
- g_print ("obj: x: %d y: %d width: %d height: %d\n", x, y, width, height);
- x = y = width = height = 0;
- atk_component_get_extents (ATK_COMPONENT (obj), &x, &y, &width, &height,
- ATK_XY_WINDOW);
- g_print ("obj: x: %d y: %d width: %d height: %d\n", x, y, width, height);
- parent = atk_object_get_parent (obj);
- x = y = width = height = 0;
- atk_component_get_extents (ATK_COMPONENT (parent), &x, &y, &width, &height,
- ATK_XY_SCREEN);
- g_print ("parent: x: %d y: %d width: %d height: %d\n", x, y, width, height);
- x = y = width = height = 0;
- atk_component_get_extents (ATK_COMPONENT (parent), &x, &y, &width, &height,
- ATK_XY_WINDOW);
- g_print ("parent: x: %d y: %d width: %d height: %d\n", x, y, width, height);
-
- child = atk_object_ref_accessible_child (obj, 0);
- x = y = width = height = 0;
- atk_component_get_extents (ATK_COMPONENT (child), &x, &y, &width, &height,
- ATK_XY_SCREEN);
- g_print ("child: x: %d y: %d width: %d height: %d\n", x, y, width, height);
- x = y = width = height = 0;
- atk_component_get_extents (ATK_COMPONENT (child), &x, &y, &width, &height,
- ATK_XY_WINDOW);
- g_print ("child: x: %d y: %d width: %d height: %d\n", x, y, width, height);
-
- g_object_unref (child);
- }
-}
-
-
-static void
-_do_selection (AtkObject *obj)
-{
- gint i;
- gint n_children;
- AtkRole role;
- AtkObject *selection_obj;
- static gboolean done_selection = FALSE;
-
- if (done_selection)
- return;
-
- role = atk_object_get_role (obj);
-
- if (role == ATK_ROLE_FRAME)
- {
- AtkRole roles[NUM_VALID_ROLES];
-
- roles[0] = ATK_ROLE_PAGE_TAB_LIST;
-
- selection_obj = find_object_by_role (obj, roles, NUM_VALID_ROLES);
-
- if (selection_obj)
- {
- done_selection = TRUE;
- }
- else
- return;
- }
- else
- {
- return;
- }
-
- g_print ("*** Start do_selection ***\n");
-
- n_children = atk_object_get_n_accessible_children (selection_obj);
- g_print ("*** Number of notebook pages: %d\n", n_children);
-
- for (i = 0; i < n_children; i++)
- {
- if (atk_selection_is_child_selected (ATK_SELECTION (selection_obj), i))
- {
- g_print ("%d page selected\n", i);
- }
- else
- {
- g_print ("%d page not selected\n", i);
- }
- }
- /*
- * Should not be able to select all items in a notebook.
- */
- atk_selection_select_all_selection (ATK_SELECTION (selection_obj));
- i = atk_selection_get_selection_count (ATK_SELECTION (selection_obj));
- if ( i != 1)
- {
- g_print ("Unexpected selection count: %d, expected 1\n", i);
- g_print ("\t value of i is: %d\n", i);
- return;
- }
-
- for (i = 0; i < n_children; i++)
- {
- atk_selection_add_selection (ATK_SELECTION (selection_obj), i);
-
- if (atk_selection_is_child_selected (ATK_SELECTION (selection_obj), i))
- {
- g_print ("Page %d: successfully selected\n", i);
- _finish_selection (selection_obj);
- }
- else
- {
- g_print ("ERROR: child %d: selection failed\n", i);
- }
- }
- g_print ("*** End _do_selection ***\n");
- g_timeout_add (5000, _remove_page, selection_obj);
-}
-
-static gint _remove_page (gpointer data)
-{
- AtkObject *obj = ATK_OBJECT (data);
- GtkWidget *widget = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
-
- g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
- gtk_notebook_remove_page (GTK_NOTEBOOK (widget), 4);
- return FALSE;
-}
-
-static gint _finish_selection (gpointer data)
-{
- AtkObject *obj = ATK_OBJECT (data);
- AtkObject *selected;
- AtkObject *parent_object;
- GtkWidget *parent_widget;
- gint i, index;
-
- g_print ("\t*** Start Finish selection ***\n");
-
- i = atk_selection_get_selection_count (ATK_SELECTION (obj));
- if (i != 1)
- {
- g_print ("\tUnexpected selection count: %d, expected 1\n", i);
- return FALSE;
- }
- selected = atk_selection_ref_selection (ATK_SELECTION (obj), 0);
- g_return_val_if_fail (selected != NULL, FALSE);
-
- g_print ("\t*** Selected Item ***\n");
- index = atk_object_get_index_in_parent (selected);
- g_print ("\tIndex in parent is: %d\n", index);
-
- parent_object = atk_object_get_parent (selected);
- g_return_val_if_fail (ATK_IS_OBJECT (parent_object), FALSE);
- g_return_val_if_fail (parent_object == obj, FALSE);
- parent_widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent_object));
- g_return_val_if_fail (GTK_IS_NOTEBOOK (parent_widget), FALSE);
-
- _print_type (selected);
- i = atk_selection_get_selection_count (ATK_SELECTION (obj));
- g_return_val_if_fail (i == 1, FALSE);
- g_object_unref (selected);
- g_print ("\t*** End Finish selection ***\n");
- return FALSE;
-}
-
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_do_selection);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testnotebook Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <gtk/gtk.h>
-#include "testlib.h"
-
-static void _print_accessible (AtkObject *obj);
-static void _print_type (AtkObject *obj);
-static void _print_states (AtkObject *obj);
-static void _check_children (AtkObject *obj);
-static void _check_relation (AtkObject *obj);
-static void _create_event_watcher (void);
-static void _focus_handler (AtkObject *obj, gboolean focus_in);
-static gboolean _children_changed (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-
-static guint id;
-
-static void _print_states (AtkObject *obj)
-{
- AtkStateSet *state_set;
- gint i;
-
- state_set = atk_object_ref_state_set (obj);
-
- g_print ("*** Start states ***\n");
- for (i = 0; i < 64; i++)
- {
- AtkStateType one_state;
- const gchar *name;
-
- if (atk_state_set_contains_state (state_set, i))
- {
- one_state = i;
-
- name = atk_state_type_get_name (one_state);
-
- if (name)
- g_print("%s\n", name);
- }
- }
- g_object_unref (state_set);
- g_print ("*** End states ***\n");
-}
-
-static void _print_type (AtkObject *obj)
-{
- const gchar * typename = NULL;
- const gchar * name = NULL;
- AtkRole role;
- static gboolean in_print_type = FALSE;
-
- if (GTK_IS_ACCESSIBLE (obj))
- {
- GtkWidget* widget = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- typename = g_type_name (G_OBJECT_TYPE (widget));
- g_print ("Widget type name: %s\n", typename ? typename : "NULL");
- }
- typename = g_type_name (G_OBJECT_TYPE (obj));
- g_print ("Accessible type name: %s\n", typename ? typename : "NULL");
- name = atk_object_get_name (obj);
- g_print("Accessible Name: %s\n", (name) ? name : "NULL");
- role = atk_object_get_role (obj);
- g_print ("Accessible Role: %s\n", atk_role_get_name (role));
-
- if (ATK_IS_COMPONENT (obj))
- {
- gint x, y, width, height;
- AtkStateSet *states;
-
- _print_states (obj);
- states = atk_object_ref_state_set (obj);
- if (atk_state_set_contains_state (states, ATK_STATE_VISIBLE))
- {
- AtkObject *parent;
-
- atk_component_get_extents (ATK_COMPONENT (obj),
- &x, &y, &width, &height,
- ATK_XY_SCREEN);
- g_print ("ATK_XY_SCREEN: x: %d y: %d width: %d height: %d\n",
- x, y, width, height);
-
- atk_component_get_extents (ATK_COMPONENT (obj),
- &x, &y, &width, &height,
- ATK_XY_WINDOW);
- g_print ("ATK_XY_WINDOW: x: %d y: %d width: %d height: %d\n",
- x, y, width, height);
- if (atk_state_set_contains_state (states, ATK_STATE_SHOWING) &&
- ATK_IS_TEXT (obj))
- {
- gint offset;
-
- atk_text_get_character_extents (ATK_TEXT (obj), 1,
- &x, &y, &width, &height,
- ATK_XY_WINDOW);
- g_print ("Character extents : %d %d %d %d\n",
- x, y, width, height);
- if (width != 0 && height != 0)
- {
- offset = atk_text_get_offset_at_point (ATK_TEXT (obj),
- x, y,
- ATK_XY_WINDOW);
- if (offset != 1)
- {
- g_print ("Wrong offset returned (%d) %d\n", 1, offset);
- }
- }
- }
- if (in_print_type)
- return;
-
- parent = atk_object_get_parent (obj);
- if (!ATK_IS_COMPONENT (parent))
- {
- /* Assume toplevel */
- g_object_unref (G_OBJECT (states));
- return;
- }
-#if 0
- obj1 = atk_component_ref_accessible_at_point (ATK_COMPONENT (parent),
- x, y, ATK_XY_WINDOW);
- if (obj != obj1)
- {
- g_print ("Inconsistency between object and ref_accessible_at_point\n");
- in_print_type = TRUE;
- _print_type (obj1);
- in_print_type = FALSE;
- }
-#endif
- }
- g_object_unref (G_OBJECT (states));
- }
-}
-
-static void _print_accessible (AtkObject *obj)
-{
- GtkWidget* widget = NULL;
- AtkObject* parent_atk;
- AtkObject* ref_obj;
- AtkRole role;
- static gboolean first_time = TRUE;
-
- if (first_time)
- {
- first_time = FALSE;
- atk_add_global_event_listener (_children_changed,
- "Atk:AtkObject:children_changed");
- }
-
- /*
- * Check that the object returned by the atk_implementor_ref_accessible()
- * for a widget is the same as the accessible object
- */
- if (GTK_IS_ACCESSIBLE (obj))
- {
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- ref_obj = atk_implementor_ref_accessible (ATK_IMPLEMENTOR (widget));
- g_assert (ref_obj == obj);
- g_object_unref (G_OBJECT (ref_obj));
- }
- /*
- * Add a focus handler so we see focus out events as well
- */
- if (ATK_IS_COMPONENT (obj))
- atk_component_add_focus_handler (ATK_COMPONENT (obj), _focus_handler);
- g_print ("Object:\n");
- _print_type (obj);
- _print_states (obj);
-
- /*
- * Get the parent object
- */
- parent_atk = atk_object_get_parent (obj);
- if (parent_atk)
- {
- g_print ("Parent Object:\n");
- _print_type (parent_atk);
- parent_atk = atk_object_get_parent (parent_atk);
- if (parent_atk)
- {
- g_print ("Grandparent Object:\n");
- _print_type (parent_atk);
- }
- }
- else
- {
- g_print ("No parent\n");
- }
-
- role = atk_object_get_role (obj);
-
- if ((role == ATK_ROLE_FRAME) || (role == ATK_ROLE_DIALOG))
- {
- _check_children (obj);
- }
-}
-
-static void _check_relation (AtkObject *obj)
-{
- AtkRelationSet* relation_set = atk_object_ref_relation_set (obj);
- gint n_relations, i;
-
- g_return_if_fail (relation_set);
-
- n_relations = atk_relation_set_get_n_relations (relation_set);
- for (i = 0; i < n_relations; i++)
- {
- AtkRelation* relation = atk_relation_set_get_relation (relation_set, i);
-
- g_print ("Index: %d Relation type: %d Number: %d\n", i,
- atk_relation_get_relation_type (relation),
- atk_relation_get_target (relation)->len);
- }
- g_object_unref (relation_set);
-}
-
-static void _check_children (AtkObject *obj)
-{
- gint n_children, i;
- AtkLayer layer;
- AtkRole role;
-
- g_print ("Start Check Children\n");
- n_children = atk_object_get_n_accessible_children (obj);
- g_print ("Number of children: %d\n", n_children);
-
- role = atk_object_get_role (obj);
-
- if (ATK_IS_COMPONENT (obj))
- {
- atk_component_add_focus_handler (ATK_COMPONENT (obj), _focus_handler);
- layer = atk_component_get_layer (ATK_COMPONENT (obj));
- if (role == ATK_ROLE_MENU)
- g_assert (layer == ATK_LAYER_POPUP);
- else
- g_print ("Layer: %d\n", layer);
- }
-
- for (i = 0; i < n_children; i++)
- {
- AtkObject *child;
- AtkObject *parent;
- int j;
-
- child = atk_object_ref_accessible_child (obj, i);
- parent = atk_object_get_parent (child);
- j = atk_object_get_index_in_parent (child);
- _print_type (child);
- _check_relation (child);
- _check_children (child);
- if (obj != parent)
- {
- g_print ("*** Inconsistency between atk_object_get_parent() and "
- "atk_object_ref_accessible_child() ***\n");
- _print_type (child);
- _print_type (obj);
- if (parent)
- _print_type (parent);
- }
- g_object_unref (G_OBJECT (child));
-
- if (j != i)
- g_print ("*** Inconsistency between parent and children %d %d ***\n",
- i, j);
- }
- g_print ("End Check Children\n");
-}
-
-static gboolean
-_children_changed (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- guint index;
- gpointer target;
- const gchar *target_name = "NotAtkObject";
-
- object = g_value_get_object (param_values + 0);
- index = g_value_get_uint (param_values + 1);
- target = g_value_get_pointer (param_values + 2);
- if (G_IS_OBJECT (target))
- {
- if (ATK_IS_OBJECT (target))
- {
- target_name = atk_object_get_name (target);
- }
- if (!target_name)
- target_name = g_type_name (G_OBJECT_TYPE (G_OBJECT (target)));
- }
- else
- {
- if (!target)
- {
- AtkObject *child;
-
- child = atk_object_ref_accessible_child (ATK_OBJECT (object), index);
- if (child)
- {
- target_name = g_type_name (G_OBJECT_TYPE (G_OBJECT (child)));
- g_object_unref (child);
- }
- }
- }
- g_print ("_children_watched: %s %s %s index: %d\n",
- g_type_name (G_OBJECT_TYPE (object)),
- g_quark_to_string (ihint->detail),
- target_name, index);
- return TRUE;
-}
-
-static void
-_create_event_watcher (void)
-{
- /*
- * _print_accessible() will be called for an accessible object when its
- * widget receives focus.
- */
- id = atk_add_focus_tracker (_print_accessible);
-}
-
-static void
-_focus_handler (AtkObject *obj, gboolean focus_in)
-{
- g_print ("In _focus_handler focus_in: %s\n", focus_in ? "true" : "false");
- _print_type (obj);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testobject Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <string.h>
-#include <stdlib.h>
-#include <gtk/gtk.h>
-#include <testlib.h>
-
-static gint _test_paned (gpointer data);
-static void _check_paned (AtkObject *obj);
-
-static void _property_change_handler (AtkObject *obj,
- AtkPropertyValues *values);
-
-#define NUM_VALID_ROLES 1
-static gint last_position;
-
-static void _property_change_handler (AtkObject *obj,
- AtkPropertyValues *values)
-{
- const gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
- const gchar *name = atk_object_get_name (obj);
-
- g_print ("_property_change_handler: Accessible Type: %s\n",
- type_name ? type_name : "NULL");
- g_print ("_property_change_handler: Accessible name: %s\n",
- name ? name : "NULL");
- g_print ("_property_change_handler: PropertyName: %s\n",
- values->property_name ? values->property_name: "NULL");
- if (strcmp (values->property_name, "accessible-value") == 0)
- {
- GValue *value, val;
- int position;
- value = &val;
-
- memset (value, 0, sizeof (GValue));
- atk_value_get_current_value (ATK_VALUE (obj), value);
- g_return_if_fail (G_VALUE_HOLDS_INT (value));
- position = g_value_get_int (value);
- g_print ("Position is %d previous position was %d\n",
- position, last_position);
- last_position = position;
- atk_value_get_minimum_value (ATK_VALUE (obj), value);
- g_return_if_fail (G_VALUE_HOLDS_INT (value));
- position = g_value_get_int (value);
- g_print ("Minimum Value is %d\n", position);
- atk_value_get_maximum_value (ATK_VALUE (obj), value);
- g_return_if_fail (G_VALUE_HOLDS_INT (value));
- position = g_value_get_int (value);
- g_print ("Maximum Value is %d\n", position);
- }
-}
-
-static gint _test_paned (gpointer data)
-{
- AtkObject *obj = ATK_OBJECT (data);
- AtkRole role = atk_object_get_role (obj);
- static gint times = 0;
-
- if (role == ATK_ROLE_SPLIT_PANE)
- {
- GValue *value, val;
- int position;
- value = &val;
-
- memset (value, 0, sizeof (GValue));
- atk_value_get_current_value (ATK_VALUE (obj), value);
- g_return_val_if_fail (G_VALUE_HOLDS_INT (value), FALSE);
- position = g_value_get_int (value);
- g_print ("Position is : %d\n", position);
- last_position = position;
- position *= 2;
- g_value_set_int (value, position);
- atk_value_set_current_value (ATK_VALUE (obj), value);
- times++;
- }
- if (times < 4)
- return TRUE;
- else
- return FALSE;
-}
-
-static void _check_paned (AtkObject *obj)
-{
- static gboolean done_paned = FALSE;
- AtkRole role;
-
- role = atk_object_get_role (obj);
-
- if (role == ATK_ROLE_FRAME)
- {
- AtkRole roles[NUM_VALID_ROLES];
- AtkObject *paned_obj;
-
- if (done_paned)
- return;
-
- roles[0] = ATK_ROLE_SPLIT_PANE;
-
- paned_obj = find_object_by_role (obj, roles, NUM_VALID_ROLES);
-
- if (paned_obj)
- {
- if (!done_paned)
- {
- done_paned = TRUE;
- }
- atk_object_connect_property_change_handler (paned_obj,
- (AtkPropertyChangeHandler*) _property_change_handler);
- g_timeout_add (2000, _test_paned, paned_obj);
- }
-
- return;
- }
- if (role != ATK_ROLE_COMBO_BOX)
- return;
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_paned);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testpaned Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <string.h>
-#include <stdlib.h>
-#include <atk/atk.h>
-#include <gtk/gtk.h>
-#include <testlib.h>
-
-static void _traverse_children (AtkObject *obj);
-static void _add_handler (AtkObject *obj);
-static void _check_properties (AtkObject *obj);
-static void _property_change_handler (AtkObject *obj,
- AtkPropertyValues *values);
-static void _state_changed (AtkObject *obj,
- const gchar *name,
- gboolean set);
-static void _selection_changed (AtkObject *obj);
-static void _visible_data_changed (AtkObject *obj);
-static void _model_changed (AtkObject *obj);
-static void _create_event_watcher (void);
-
-static guint id;
-
-static void
-_state_changed (AtkObject *obj,
- const gchar *name,
- gboolean set)
-{
- g_print ("_state_changed: %s: state %s %s\n",
- g_type_name (G_OBJECT_TYPE (obj)),
- set ? "is" : "was", name);
-}
-
-static void
-_selection_changed (AtkObject *obj)
-{
- gchar *type;
-
- if (ATK_IS_TEXT (obj))
- type = "text";
- else if (ATK_IS_SELECTION (obj))
- type = "child selection";
- else
- {
- g_assert_not_reached();
- return;
- }
-
- g_print ("In selection_changed signal handler for %s, object type: %s\n",
- type, g_type_name (G_OBJECT_TYPE (obj)));
-}
-
-static void
-_visible_data_changed (AtkObject *obj)
-{
- g_print ("In visible_data_changed signal handler, object type: %s\n",
- g_type_name (G_OBJECT_TYPE (obj)));
-}
-
-static void
-_model_changed (AtkObject *obj)
-{
- g_print ("In model_changed signal handler, object type: %s\n",
- g_type_name (G_OBJECT_TYPE (obj)));
-}
-
-static void
-_property_change_handler (AtkObject *obj,
- AtkPropertyValues *values)
-{
- const gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
- const gchar *name = atk_object_get_name (obj);
-
- g_print ("_property_change_handler: Accessible Type: %s\n",
- type_name ? type_name : "NULL");
- g_print ("_property_change_handler: Accessible name: %s\n",
- name ? name : "NULL");
- g_print ("_property_change_handler: PropertyName: %s\n",
- values->property_name ? values->property_name: "NULL");
- if (G_VALUE_HOLDS_STRING (&values->new_value))
- g_print ("_property_change_handler: PropertyValue: %s\n",
- g_value_get_string (&values->new_value));
- else if (strcmp (values->property_name, "accessible-child") == 0)
- {
- if (G_IS_VALUE (&values->old_value))
- {
- g_print ("Child is removed: %s\n",
- g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->old_value))));
- }
- if (G_IS_VALUE (&values->new_value))
- {
- g_print ("Child is added: %s\n",
- g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->new_value))));
- }
- }
- else if (strcmp (values->property_name, "accessible-parent") == 0)
- {
- if (G_IS_VALUE (&values->old_value))
- {
- g_print ("Parent is removed: %s\n",
- g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->old_value))));
- }
- if (G_IS_VALUE (&values->new_value))
- {
- g_print ("Parent is added: %s\n",
- g_type_name (G_TYPE_FROM_INSTANCE (g_value_get_pointer (&values->new_value))));
- }
- }
- else if (strcmp (values->property_name, "accessible-value") == 0)
- {
- if (G_VALUE_HOLDS_DOUBLE (&values->new_value))
- {
- g_print ("Value now is (double) %f\n",
- g_value_get_double (&values->new_value));
- }
- }
-}
-
-static void
-_traverse_children (AtkObject *obj)
-{
- gint n_children, i;
- AtkRole role;
-
- role = atk_object_get_role (obj);
-
- if ((role == ATK_ROLE_TABLE) ||
- (role == ATK_ROLE_TREE_TABLE))
- return;
-
- n_children = atk_object_get_n_accessible_children (obj);
- for (i = 0; i < n_children; i++)
- {
- AtkObject *child;
-
- child = atk_object_ref_accessible_child (obj, i);
- _add_handler (child);
- _traverse_children (child);
- g_object_unref (G_OBJECT (child));
- }
-}
-
-static void
-_add_handler (AtkObject *obj)
-{
- static GPtrArray *obj_array = NULL;
- gboolean found = FALSE;
- gint i;
-
- /*
- * We create a property handler for each object if one was not associated
- * with it already.
- *
- * We add it to our array of objects which have property handlers; if an
- * object is destroyed it remains in the array.
- */
- if (obj_array == NULL)
- obj_array = g_ptr_array_new ();
-
- for (i = 0; i < obj_array->len; i++)
- {
- if (obj == g_ptr_array_index (obj_array, i))
- {
- found = TRUE;
- break;
- }
- }
- if (!found)
- {
- atk_object_connect_property_change_handler (obj,
- (AtkPropertyChangeHandler*) _property_change_handler);
- g_signal_connect (obj, "state-change",
- (GCallback) _state_changed, NULL);
- if (ATK_IS_SELECTION (obj))
- g_signal_connect (obj, "selection_changed",
- (GCallback) _selection_changed, NULL);
- g_signal_connect (obj, "visible_data_changed",
- (GCallback) _visible_data_changed, NULL);
- if (ATK_IS_TABLE (obj))
- g_signal_connect (obj, "model_changed",
- (GCallback) _model_changed, NULL);
- g_ptr_array_add (obj_array, obj);
- }
-}
-
-static void
-_check_properties (AtkObject *obj)
-{
- AtkRole role;
-
- g_print ("Start of _check_properties: %s\n",
- g_type_name (G_OBJECT_TYPE (obj)));
-
- _add_handler (obj);
-
- role = atk_object_get_role (obj);
- if (role == ATK_ROLE_FRAME ||
- role == ATK_ROLE_DIALOG)
- {
- /*
- * Add handlers to all children.
- */
- _traverse_children (obj);
- }
- g_print ("End of _check_properties\n");
-}
-
-static void
-_create_event_watcher (void)
-{
- id = atk_add_focus_tracker (_check_properties);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testprops Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <string.h>
-#include <atk/atk.h>
-#include <gtk/gtk.h>
-
-/*
- * This module tests the selection interface on menu items.
- * To use this module run the test program testgtk and use the menus
- * option.
- */
-static void _do_selection (AtkObject *obj);
-static gint _finish_selection (gpointer data);
-static AtkObject* _find_object (AtkObject* obj, AtkRole role);
-static void _print_type (AtkObject *obj);
-
-static AtkObject*
-_find_object (AtkObject *obj,
- AtkRole role)
-{
- /*
- * Find the first object which is a descendant of the specified object
- * which matches the specified role.
- *
- * This function returns a reference to the AtkObject which should be
- * removed when finished with the object.
- */
- gint i;
- gint n_children;
- AtkObject *child;
-
- n_children = atk_object_get_n_accessible_children (obj);
- for (i = 0; i < n_children; i++)
- {
- AtkObject* found_obj;
-
- child = atk_object_ref_accessible_child (obj, i);
- if (atk_object_get_role (child) == role)
- {
- return child;
- }
- found_obj = _find_object (child, role);
- g_object_unref (child);
- if (found_obj)
- {
- return found_obj;
- }
- }
- return NULL;
-}
-
-static void _print_type (AtkObject *obj)
-{
- const gchar * typename = NULL;
- const gchar * name = NULL;
- AtkRole role;
-
- if (GTK_IS_ACCESSIBLE (obj))
- {
- GtkWidget* widget = NULL;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
- typename = g_type_name (G_OBJECT_TYPE (widget));
- g_print ("Widget type name: %s\n", typename ? typename : "NULL");
- }
- typename = g_type_name (G_OBJECT_TYPE (obj));
- g_print ("Accessible type name: %s\n", typename ? typename : "NULL");
- name = atk_object_get_name (obj);
- g_print("Accessible Name: %s\n", (name) ? name : "NULL");
- role = atk_object_get_role(obj);
- g_print ("Accessible Role: %d\n", role);
-}
-
-static void
-_do_selection (AtkObject *obj)
-{
- gint i;
- AtkObject *selected;
- AtkRole role;
- AtkObject *selection_obj;
-
- role = atk_object_get_role (obj);
-
- if ((role == ATK_ROLE_FRAME) &&
- (strcmp (atk_object_get_name (obj), "menus") == 0))
- {
- selection_obj = _find_object (obj, ATK_ROLE_MENU_BAR);
- if (selection_obj)
- {
- g_object_unref (selection_obj);
- }
- }
- else if (role == ATK_ROLE_COMBO_BOX)
- {
- selection_obj = obj;
- }
- else
- return;
-
- g_print ("*** Start do_selection ***\n");
-
-
- if (!selection_obj)
- {
- g_print ("no selection_obj\n");
- return;
- }
-
- i = atk_selection_get_selection_count (ATK_SELECTION (selection_obj));
- if (i != 0)
- {
- for (i = 0; i < atk_object_get_n_accessible_children (selection_obj); i++)
- {
- if (atk_selection_is_child_selected (ATK_SELECTION (selection_obj), i))
- {
- g_print ("%d child selected\n", i);
- }
- else
- {
- g_print ("%d child not selected\n", i);
- }
- }
- }
- /*
- * Should not be able to select all items on a menu bar
- */
- atk_selection_select_all_selection (ATK_SELECTION (selection_obj));
- i = atk_selection_get_selection_count (ATK_SELECTION (selection_obj));
- if ( i != 0)
- {
- g_print ("Unexpected selection count: %d, expected 0\n", i);
- return;
- }
- /*
- * There should not be any items selected
- */
- selected = atk_selection_ref_selection (ATK_SELECTION (selection_obj), 0);
- if ( selected != NULL)
- {
- g_print ("Unexpected selection: %d, expected 0\n", i);
- }
- atk_selection_add_selection (ATK_SELECTION (selection_obj), 1);
- g_timeout_add (2000, _finish_selection, selection_obj);
- g_print ("*** End _do_selection ***\n");
-}
-
-static gint _finish_selection (gpointer data)
-{
- AtkObject *obj = ATK_OBJECT (data);
- AtkObject *selected;
- gint i;
- gboolean is_selected;
-
- g_print ("*** Start Finish selection ***\n");
-
- /*
- * If being run for for menus, at this point menu item foo should be
- * selected which means that its submenu should be visible.
- */
- i = atk_selection_get_selection_count (ATK_SELECTION (obj));
- if (i != 1)
- {
- g_print ("Unexpected selection count: %d, expected 1\n", i);
- return FALSE;
- }
- selected = atk_selection_ref_selection (ATK_SELECTION (obj), 0);
- g_return_val_if_fail (selected != NULL, FALSE);
- g_print ("*** Selected Item ***\n");
- _print_type (selected);
- g_object_unref (selected);
- is_selected = atk_selection_is_child_selected (ATK_SELECTION (obj), 1);
- g_return_val_if_fail (is_selected, FALSE);
- is_selected = atk_selection_is_child_selected (ATK_SELECTION (obj), 0);
- g_return_val_if_fail (!is_selected, FALSE);
- selected = atk_selection_ref_selection (ATK_SELECTION (obj), 1);
- g_return_val_if_fail (selected == NULL, FALSE);
- atk_selection_remove_selection (ATK_SELECTION (obj), 0);
- i = atk_selection_get_selection_count (ATK_SELECTION (obj));
- g_return_val_if_fail (i == 0, FALSE);
- selected = atk_selection_ref_selection (ATK_SELECTION (obj), 0);
- g_return_val_if_fail (selected == NULL, FALSE);
- g_print ("*** End Finish selection ***\n");
- return FALSE;
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_do_selection);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testselection Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <string.h>
-#include <glib-object.h>
-#include <atk/atk.h>
-
-/*
- * To use this test module, run the test program testgtk and click on
- * statusbar
- */
-
-static void _check_statusbar (AtkObject *obj);
-static AtkObject* _find_object (AtkObject* obj, AtkRole role);
-static void _notify_handler (GObject *obj, GParamSpec *pspec);
-static void _property_change_handler (AtkObject *obj,
- AtkPropertyValues *values);
-
-static AtkObject*
-_find_object (AtkObject *obj,
- AtkRole role)
-{
- /*
- * Find the first object which is a descendant of the specified object
- * which matches the specified role.
- *
- * This function returns a reference to the AtkObject which should be
- * removed when finished with the object.
- */
- gint i;
- gint n_children;
- AtkObject *child;
-
- n_children = atk_object_get_n_accessible_children (obj);
- for (i = 0; i < n_children; i++)
- {
- AtkObject* found_obj;
-
- child = atk_object_ref_accessible_child (obj, i);
- if (atk_object_get_role (child) == role)
- {
- return child;
- }
- found_obj = _find_object (child, role);
- g_object_unref (child);
- if (found_obj)
- {
- return found_obj;
- }
- }
- return NULL;
-}
-
-static void _property_change_handler (AtkObject *obj,
- AtkPropertyValues *values)
-{
- const gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
- const gchar *name = atk_object_get_name (obj);
-
- g_print ("_property_change_handler: Accessible Type: %s\n",
- type_name ? type_name : "NULL");
- g_print ("_property_change_handler: Accessible name: %s\n",
- name ? name : "NULL");
- g_print ("_property_change_handler: PropertyName: %s\n",
- values->property_name ? values->property_name: "NULL");
- if (G_VALUE_HOLDS_STRING (&values->new_value))
- g_print ("_property_change_handler: PropertyValue: %s\n",
- g_value_get_string (&values->new_value));
-}
-
-static void _check_statusbar (AtkObject *obj)
-{
- AtkRole role;
- AtkObject *statusbar, *label;
-
- role = atk_object_get_role (obj);
- if (role != ATK_ROLE_FRAME)
- return;
-
- statusbar = _find_object (obj, ATK_ROLE_STATUSBAR);
- if (!statusbar)
- return;
- g_print ("_check_statusbar\n");
- label = atk_object_ref_accessible_child (statusbar, 0);
- g_return_if_fail (label == NULL);
-
- /*
- * We get notified of changes to the label
- */
- g_signal_connect_closure_by_id (statusbar,
- g_signal_lookup ("notify",
- G_OBJECT_TYPE (statusbar)),
- 0,
- g_cclosure_new (G_CALLBACK (_notify_handler),
- NULL, NULL),
- FALSE);
- atk_object_connect_property_change_handler (statusbar,
- (AtkPropertyChangeHandler*) _property_change_handler);
-
-}
-
-static void
-_notify_handler (GObject *obj, GParamSpec *pspec)
-{
- AtkObject *atk_obj = ATK_OBJECT (obj);
- const gchar *name;
-
- g_print ("_notify_handler: property: %s\n", pspec->name);
- if (strcmp (pspec->name, "accessible-name") == 0)
- {
- name = atk_object_get_name (atk_obj);
- g_print ("_notify_handler: value: |%s|\n", name ? name : "<NULL>");
- }
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_statusbar);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("teststatusbar Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
+++ /dev/null
-#include <string.h>
-#include "testtextlib.h"
-
-#define NUM_ROWS_TO_LOOP 30
-
-typedef struct
-{
- GtkWidget *tb_others;
- GtkWidget *tb_ref_selection;
- GtkWidget *tb_ref_at;
- GtkWidget *tb_ref_accessible_child;
- GtkWidget *child_entry;
- GtkWidget *row_entry;
- GtkWidget *col_entry;
- GtkWidget *index_entry;
-}TestChoice;
-
-static void _check_table (AtkObject *in_obj);
-void table_runtest(AtkObject *);
-static void other_runtest(AtkObject *obj);
-static void ref_at_runtest(AtkObject *obj, gint row, gint col);
-static void ref_accessible_child_runtest(AtkObject *obj, gint childno);
-static void ref_selection_runtest (AtkObject *obj, gint index);
-static void _selection_tests(AtkObject *obj);
-static void _display_header_info(gchar *type,
- AtkObject *header_obj, gint header_num);
-static void _process_child(AtkObject *child_obj);
-
-static void _notify_table_row_inserted (GObject *obj,
- gint start_offset, gint length);
-static void _notify_table_column_inserted (GObject *obj,
- gint start_offset, gint length);
-static void _notify_table_row_deleted (GObject *obj,
- gint start_offset, gint length);
-static void _notify_table_column_deleted (GObject *obj,
- gint start_offset, gint length);
-static void _notify_table_row_reordered (GObject *obj);
-static void _notify_table_column_reordered (GObject *obj);
-static void _notify_table_child_added (GObject *obj,
- gint index, AtkObject *child);
-static void _notify_table_child_removed (GObject *obj,
- gint index, AtkObject *child);
-static void _property_signal_connect (AtkObject *obj);
-static void _property_change_handler (AtkObject *obj,
- AtkPropertyValues *values);
-
-static gboolean tested_set_headers = FALSE;
-static void test_choice_gui (AtkObject **obj);
-static void nogui_runtest (AtkObject *obj);
-static void nogui_ref_at_runtest (AtkObject *obj);
-static void nogui_process_child (AtkObject *obj);
-
-static TestChoice *tc;
-static gint g_visibleGUI = 0;
-static AtkTable *g_table = NULL;
-static AtkObject *current_obj = NULL;
-gboolean g_done = FALSE;
-gboolean g_properties = TRUE;
-
-/*
- * destroy
- *
- * Destroy Callback
- *
- */
-static void destroy (GtkWidget *widget, gpointer data)
-{
- gtk_main_quit();
-}
-
-static void choicecb (GtkWidget *widget, gpointer data)
-{
- AtkObject **ptr_to_obj = (AtkObject **)data;
- AtkObject *obj = *ptr_to_obj;
-
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tc->tb_others)))
- {
- other_runtest(obj);
- }
- else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tc->tb_ref_selection)))
- {
- const gchar *indexstr;
- gint index;
-
- indexstr = gtk_entry_get_text(GTK_ENTRY(tc->index_entry));
- index = string_to_int((gchar *)indexstr);
-
- ref_selection_runtest(obj, index);
- }
- else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tc->tb_ref_at)))
- {
- const gchar *rowstr, *colstr;
- gint row, col;
-
- rowstr = gtk_entry_get_text(GTK_ENTRY(tc->row_entry));
- colstr = gtk_entry_get_text(GTK_ENTRY(tc->col_entry));
- row = string_to_int((gchar *)rowstr);
- col = string_to_int((gchar *)colstr);
-
- ref_at_runtest(obj, row, col);
- }
- else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tc->tb_ref_accessible_child)))
- {
- const gchar *childstr;
- gint childno;
- childstr = gtk_entry_get_text(GTK_ENTRY(tc->child_entry));
- childno = string_to_int((gchar *)childstr);
-
- ref_accessible_child_runtest(obj, childno);
- }
-}
-
-static void _check_table (AtkObject *in_obj)
-{
- AtkObject *obj = NULL;
- const char *no_properties;
- const char *no_gui;
-
- no_properties = g_getenv ("TEST_ACCESSIBLE_NO_PROPERTIES");
- no_gui = g_getenv ("TEST_ACCESSIBLE_NO_GUI");
-
- if (no_properties != NULL)
- g_properties = FALSE;
- if (no_gui != NULL)
- g_visibleGUI = 1;
-
- obj = find_object_by_type(in_obj, "GailTreeView");
- if (obj != NULL)
- g_print("Found GailTreeView table in child!\n");
- else
- {
- obj = find_object_by_type(in_obj, "GailCList");
- if (obj != NULL)
- g_print("Found GailCList in child!\n");
- else
- {
- g_print("No object found %s\n", g_type_name (G_OBJECT_TYPE (in_obj)));
- return;
- }
- }
-
- g_print ("In _check_table\n");
-
- if (!already_accessed_atk_object(obj))
- {
- /* Set up signal handlers */
-
- g_print ("Adding signal handler\n");
- g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("column_inserted", G_OBJECT_TYPE (obj)),
- 0,
- g_cclosure_new (G_CALLBACK (_notify_table_column_inserted),
- NULL, NULL),
- FALSE);
- g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("row_inserted", G_OBJECT_TYPE (obj)),
- 0,
- g_cclosure_new (G_CALLBACK (_notify_table_row_inserted),
- NULL, NULL),
- FALSE);
- g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("column_deleted", G_OBJECT_TYPE (obj)),
- 0,
- g_cclosure_new (G_CALLBACK (_notify_table_column_deleted),
- NULL, NULL),
- FALSE);
- g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("row_deleted", G_OBJECT_TYPE (obj)),
- 0,
- g_cclosure_new (G_CALLBACK (_notify_table_row_deleted),
- NULL, NULL),
- FALSE);
- g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("column_reordered", G_OBJECT_TYPE (obj)),
- 0,
- g_cclosure_new (G_CALLBACK (_notify_table_column_reordered),
- NULL, NULL),
- FALSE);
- g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("row_reordered", G_OBJECT_TYPE (obj)),
- 0,
- g_cclosure_new (G_CALLBACK (_notify_table_row_reordered),
- NULL, NULL),
- FALSE);
- g_signal_connect_closure (obj, "children_changed::add",
- g_cclosure_new (G_CALLBACK (_notify_table_child_added),
- NULL, NULL),
- FALSE);
-
- g_signal_connect_closure (obj, "children_changed::remove",
- g_cclosure_new (G_CALLBACK (_notify_table_child_removed),
- NULL, NULL),
- FALSE);
-
- }
- g_table = ATK_TABLE(obj);
-
- atk_object_connect_property_change_handler (obj,
- (AtkPropertyChangeHandler*) _property_change_handler);
-
- current_obj = obj;
- /*
- * The use of ¤t_obj allows us to change the object being processed
- * in the GUI.
- */
- if (g_visibleGUI != 1)
- test_choice_gui(¤t_obj);
- else if (no_gui != NULL)
- nogui_runtest(obj);
-}
-
-static
-void other_runtest(AtkObject *obj)
-{
- AtkObject *header_obj;
- AtkObject *out_obj;
- const gchar *out_string;
- GString *out_desc;
- gint n_cols, n_rows;
- gint rows_to_loop = NUM_ROWS_TO_LOOP;
- gint i, j;
- out_desc = g_string_sized_new(256);
-
- n_cols = atk_table_get_n_columns(ATK_TABLE(obj));
- n_rows = atk_table_get_n_rows(ATK_TABLE(obj));
-
- g_print ("Number of columns is %d\n", n_cols);
- g_print ("Number of rows is %d\n", n_rows);
-
- /* Loop NUM_ROWS_TO_LOOP rows if possible */
- if (n_rows < NUM_ROWS_TO_LOOP)
- rows_to_loop = n_rows;
-
- g_print ("\n");
-
- /* Caption */
-
- out_obj = atk_table_get_caption(ATK_TABLE(obj));
- if (out_obj != NULL)
- {
- out_string = atk_object_get_name (out_obj);
- if (out_string)
- g_print("Caption Name is <%s>\n", out_string);
- else
- g_print("Caption has no name\n");
- }
- else
- g_print("No caption\n");
-
- /* Column descriptions and headers */
-
- g_print ("\n");
- for (i=0; i < n_cols; i++)
- {
- /* check default */
- out_string = atk_table_get_column_description(ATK_TABLE(obj), i);
- if (out_string != NULL)
- g_print("%d: Column description is <%s>\n", i, out_string);
- else
- g_print("%d: Column description is <NULL>\n", i);
-
- /* check setting a new value */
-
- g_string_printf(out_desc, "new column description %d", i);
-
- if (out_string == NULL || strcmp (out_string, out_desc->str) != 0)
- {
- g_print("%d, Setting the column description to <%s>\n",
- i, out_desc->str);
- atk_table_set_column_description(ATK_TABLE(obj), i, out_desc->str);
- out_string = atk_table_get_column_description(ATK_TABLE(obj), i);
- if (out_string != NULL)
- g_print("%d: Column description is <%s>\n", i, out_string);
- else
- g_print("%d: Column description is <NULL>\n", i);
- }
-
- /* Column header */
- header_obj = atk_table_get_column_header(ATK_TABLE(obj), i);
- _display_header_info("Column", header_obj, i);
- }
-
- /* Row description */
-
- g_print ("\n");
-
- for (i=0; i < rows_to_loop; i++)
- {
- out_string = atk_table_get_row_description(ATK_TABLE(obj), i);
- if (out_string != NULL)
- g_print("%d: Row description is <%s>\n", i, out_string);
- else
- g_print("%d: Row description is <NULL>\n", i);
-
- g_string_printf(out_desc, "new row description %d", i);
-
- if (out_string == NULL || strcmp (out_string, out_desc->str) != 0)
- {
- g_print("%d: Setting the row description to <%s>\n",
- i, out_desc->str);
- atk_table_set_row_description(ATK_TABLE(obj), i, out_desc->str);
-
- out_string = atk_table_get_row_description(ATK_TABLE(obj), i);
- if (out_string != NULL)
- g_print("%d: Row description is <%s>\n", i, out_string);
- else
- g_print("%d: Row description is <NULL>\n", i);
- }
-
- header_obj = atk_table_get_row_header(ATK_TABLE(obj), i);
- _display_header_info("Row", header_obj, i);
-
- for (j=0; j <n_cols; j++)
- {
- gint index = atk_table_get_index_at(ATK_TABLE(obj), i, j);
- gint row, column;
-
- column = atk_table_get_column_at_index (ATK_TABLE (obj), index);
- g_return_if_fail (column == j);
-
- row = atk_table_get_row_at_index (ATK_TABLE (obj), index);
- g_return_if_fail (row == i);
-
- if(atk_selection_is_child_selected(ATK_SELECTION(obj), index))
- g_print("atk_selection_is_child_selected,index = %d returns TRUE\n", index);
- /* Generic cell tests */
- /* Just test setting column headers once. */
-
- if (!tested_set_headers)
- {
- tested_set_headers = TRUE;
-
- /* Hardcode to 1,1 for now */
- g_print(
- "Testing set_column_header for column %d, to table\n",
- (n_cols - 1));
- atk_table_set_column_header(ATK_TABLE(obj), (n_cols - 1), obj);
-
- g_print("Testing set_row_header for row %d, to table\n", n_rows);
- atk_table_set_row_header(ATK_TABLE(obj), n_rows, obj);
- }
- }
- }
-
- /* row/column extents */
-
- g_print("\n");
- g_print("Row extents at 1,1 is %d\n",
- atk_table_get_row_extent_at(ATK_TABLE(obj), 1, 1));
- g_print("Column extents at 1,1 is %d\n",
- atk_table_get_column_extent_at(ATK_TABLE(obj), 1, 1));
-}
-
-static
-void ref_accessible_child_runtest(AtkObject *obj, gint child)
-{
- AtkObject *child_obj;
- /* ref_child */
- g_print ("Accessing child %d\n", child);
- child_obj = atk_object_ref_accessible_child (obj, child);
- _property_signal_connect(child_obj);
- if (child_obj != NULL)
- _process_child(child_obj);
-}
-
-static
-void ref_selection_runtest (AtkObject *obj, gint index)
-{
- AtkObject *child_obj;
-
- /* use atk_selection_ref_selection just once to check it works */
- child_obj = atk_selection_ref_selection(ATK_SELECTION(obj), index);
- if (child_obj)
- {
- g_print("child_obj gotten from atk_selection_ref_selection\n");
- g_object_unref (child_obj);
- }
- else
- g_print("NULL returned by atk_selection_ref_selection\n");
-
- _selection_tests(obj);
-}
-
-static
-void ref_at_runtest(AtkObject *obj, gint row, gint col)
-{
- AtkObject *child_obj;
- /* ref_at */
-
- g_print("Testing ref_at row %d column %d\n", row, col);
-
- child_obj = atk_table_ref_at(ATK_TABLE(obj), row, col);
- _property_signal_connect(child_obj);
-
- g_print("Row is %d, col is %d\n", row, col);
-
- _process_child(child_obj);
- if (child_obj)
- g_object_unref (child_obj);
-}
-
-/**
- * process_child
- **/
-static void
-_process_child(AtkObject *child_obj)
-{
- if (child_obj != NULL)
- {
- if (ATK_IS_TEXT(child_obj))
- {
- add_handlers(child_obj);
- setup_gui(child_obj, runtest);
- }
- else
- {
- g_print("Interface is not text!\n");
- }
-/*
- if (ATK_IS_ACTION(child_obj))
- {
- gint i, j;
- gchar *action_name;
- gchar *action_description;
- gchar *action_keybinding;
- AtkAction *action = ATK_ACTION(child_obj);
-
- i = atk_action_get_n_actions (action);
- g_print ("Supports AtkAction with %d actions.\n", i);
- for (j = 0; j < i; j++)
- {
- g_print ("Action %d:\n", j);
- action_name = atk_action_get_name (action, j);
- if (action_name)
- g_print (" Name = %s\n", action_name);
- action_description = atk_action_get_description (action, j);
- if (action_description)
- g_print (" Description = %s\n", action_description);
- action_keybinding = atk_action_get_keybinding (action, j);
- if (action_keybinding)
- g_print (" Keybinding = %s\n", action_keybinding);
- action_description = "new description";
- g_print (" Setting description to %s\n", action_description);
- atk_action_set_description (action, j, action_description);
- action_description = atk_action_get_description (action, j);
- if (action_description)
- g_print (" New description is now %s\n", action_description);
- }
- }
-*/
- }
- else
- {
- g_print("Child is NULL!\n");
- }
-}
-
-/**
- * Combined tests on AtkTable and AtkSelection on individual rows rather than
- * all of them
- **/
-static void
-_selection_tests(AtkObject *obj)
-{
- gint n_rows = 0;
- gint n_cols = 0;
- gint selection_count = 0;
- gint i = 0;
- gint *selected = NULL;
- AtkTable *table;
-
- table = ATK_TABLE (obj);
-
- n_rows = atk_table_get_selected_rows(table, &selected);
- for (i = 0; i < n_rows; i++)
- {
- g_print("atk_table_get_selected_row returns : %d\n",
- selected[i]);
- if (!atk_table_is_row_selected (table, selected[i]))
- g_print("atk_table_is_row_selected returns false for selected row %d\n",
- selected[i]);
- }
- g_free (selected);
-
- selected = NULL;
- n_cols = atk_table_get_selected_columns(table, &selected);
- for (i = 0; i < n_cols; i++)
- g_print("atk_table_get_selected_columns returns : %d\n", selected[i]);
- g_free (selected);
-
- selection_count = atk_selection_get_selection_count(ATK_SELECTION(obj));
- g_print("atk_selection_get_selection_count returns %d\n", selection_count);
-
- if (atk_table_is_row_selected(table, 2))
- {
- g_print("atk_table_is_row_selected (table, 2) returns TRUE\n");
- atk_selection_clear_selection (ATK_SELECTION (obj));
- if (atk_table_add_row_selection(table, 4))
- g_print("atk_table_add_row_selection: selected row 4\n");
- if (!atk_table_is_row_selected (table, 4))
- g_print("atk_table_is_row_selected returns false for row 2\n");
- if (atk_table_is_row_selected (table, 2))
- g_print("atk_table_is_row_selected gives false positive for row 2\n");
- }
-
- if (atk_table_is_row_selected(table, 3))
- {
- if (atk_table_remove_row_selection(table, 3))
- g_print("atk_table_remove_row_selection unselected row 3\n");
- }
-
- if (atk_table_is_selected(table, 5, 4))
- {
- atk_selection_clear_selection(ATK_SELECTION(obj));
- g_print("atk_selection_clear_selection: just cleared all selected\n");
- }
-
- if (atk_table_is_column_selected(table, 2))
- {
- g_print("atk_table_is_column_selected(obj, 2) returns TRUE\n");
- if (atk_table_add_column_selection(table, 4))
- g_print("atk_table_add_column_selection: selected column 4\n");
- g_print("atk_table_is_column_selected(obj, 2) returns TRUE\n");
- }
-
- if (atk_table_is_column_selected(table, 3))
- {
- if (atk_table_remove_column_selection(table, 3))
- g_print("atk_table_remove_column_selection: unselected column 3\n");
- }
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_table);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("TestTable Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
-
-static void
-_notify_table_row_inserted (GObject *obj, gint start_offset, gint length)
-{
- g_print ("SIGNAL - Row inserted at position %d, num of rows inserted %d!\n",
- start_offset, length);
-}
-
-static void
-_notify_table_column_inserted (GObject *obj, gint start_offset, gint length)
-{
- g_print ("SIGNAL - Column inserted at position %d, num of columns inserted %d!\n",
- start_offset, length);
-}
-
-static void
-_notify_table_row_deleted (GObject *obj, gint start_offset, gint length)
-{
- g_print ("SIGNAL - Row deleted at position %d, num of rows deleted %d!\n",
- start_offset, length);
-}
-
-static void
-_notify_table_column_deleted (GObject *obj, gint start_offset, gint length)
-{
- g_print ("SIGNAL - Column deleted at position %d, num of columns deleted %d!\n",
- start_offset, length);
-}
-
-static void
-_notify_table_row_reordered (GObject *obj)
-{
- g_print ("SIGNAL - Row reordered!\n");
-}
-
-static void
-_notify_table_column_reordered (GObject *obj)
-{
- g_print ("SIGNAL - Column reordered!\n");
-}
-
-static void _notify_table_child_added (GObject *obj,
- gint index, AtkObject *child)
-{
- g_print ("SIGNAL - Child added - index %d\n", index);
-}
-
-static void _notify_table_child_removed (GObject *obj,
- gint index, AtkObject *child)
-{
- g_print ("SIGNAL - Child removed - index %d\n", index);
-}
-
-static void
-_display_header_info(gchar *type, AtkObject *header_obj, gint header_num)
-{
- if (header_obj != NULL)
- {
- AtkRole role;
- role = atk_object_get_role(header_obj);
-
- if (role == ATK_ROLE_PUSH_BUTTON)
- {
- g_print ("%d: %s header is a push button!\n", header_num, type);
- }
- else if (role == ATK_ROLE_LABEL)
- {
- g_print ("%d: %s header is a label!\n", header_num, type);
- }
- else if (ATK_IS_TEXT(header_obj))
- {
- gchar *header_text;
-
- header_text = atk_text_get_text (ATK_TEXT (header_obj), 0, 3);
- if (header_text != NULL)
- {
- g_print("%d: %s header is a text value <%s>\n", header_num,
- type, header_text);
- }
- else
- {
- g_print("%d: %s header is a text value <NULL>\n", header_num,
- type);
- }
- }
- else
- {
- g_print ("%d: %s header is of type %s!\n", header_num,
- type, atk_role_get_name (role));
- }
- }
- else
- {
- g_print ("%d: %s header object is NULL!\n", header_num, type);
- }
-}
-
-static void _property_signal_connect (AtkObject *obj)
-{
- if (g_properties && obj != NULL)
- {
- g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("property_change", G_OBJECT_TYPE (obj)),
- 0,
- g_cclosure_new (G_CALLBACK (_property_change_handler),
- NULL, NULL),
- FALSE);
- }
-}
-
-static void
-_property_change_handler (AtkObject *obj,
- AtkPropertyValues *values)
-{
- gchar *obj_text;
- const gchar *name;
-
- if (g_table != NULL)
- {
- gint index = atk_object_get_index_in_parent(obj);
-
- if (index >= 0)
- g_print("Index is %d, row is %d, col is %d\n", index,
- atk_table_get_row_at_index(g_table, index),
- atk_table_get_column_at_index(g_table, index));
- else
- g_print ("index: %d for %s\n", index, g_type_name (G_OBJECT_TYPE (obj)));
- }
-
- if (ATK_IS_TEXT(obj))
- {
- obj_text = atk_text_get_text (ATK_TEXT (obj), 0, 15);
- if (obj_text == NULL)
- g_print(" Cell text is <NULL>\n");
- else
- g_print(" Cell text is <%s>\n", obj_text);
- }
-
- g_print(" PropertyName <%s>\n",
- values->property_name ? values->property_name: "NULL");
- g_print(" - ");
-
- if (&values->old_value != NULL && G_IS_VALUE (&values->old_value))
- {
- GType old_type = G_VALUE_TYPE (&values->old_value);
-
- switch (old_type)
- {
- case G_TYPE_INT:
- g_print("value was <%d>\n", g_value_get_int (&values->old_value));
- break;
- case G_TYPE_STRING:
- name = g_value_get_string (&values->old_value);
- if (name != NULL)
- g_print ("value was <%s>\n", name);
- else
- g_print ("value was <NULL>\n");
- break;
- default:
- g_print("value was <unknown type>\n");
- break;
- }
- }
- else
- {
- g_print("value was <not a value>\n");
- }
- g_print(" - ");
- if (&values->new_value != NULL && G_IS_VALUE (&values->new_value))
- {
- GType new_type = G_VALUE_TYPE (&values->new_value);
-
- switch (new_type)
- {
- case G_TYPE_INT:
- g_print("value is <%d>\n", g_value_get_int (&values->new_value));
- break;
- case G_TYPE_STRING:
- name = g_value_get_string (&values->new_value);
- if (name != NULL)
- g_print ("value is <%s>\n", name);
- else
- g_print ("value is <NULL>\n");
- break;
- default:
- g_print("value is <unknown type>\n");
- break;
- }
- }
- else
- {
- g_print("value is <not a value>\n");
- }
-}
-
-static
-void test_choice_gui(AtkObject **obj)
-{
- GtkWidget *window;
- GtkWidget *vbox;
- GtkWidget *hbox;
- GtkWidget *child_label;
- GtkWidget *row_label;
- GtkWidget *col_label;
- GtkWidget *index_label;
- GtkWidget *hseparator;
- GtkWidget *hbuttonbox;
- GtkWidget *button;
-
-
- tc = (TestChoice *) g_malloc (sizeof(TestChoice));
-
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(window), "Test to run");
-
- g_signal_connect(window, "destroy",
- G_CALLBACK (destroy), &window);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE);
- gtk_box_set_spacing(GTK_BOX(vbox), 10);
-
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_set_spacing(GTK_BOX(hbox), 10);
- tc->tb_ref_selection = gtk_toggle_button_new_with_label("ref_selection");
- gtk_box_pack_start (GTK_BOX (hbox), tc->tb_ref_selection, TRUE, TRUE, 0);
- index_label = gtk_label_new("index: ");
- gtk_box_pack_start (GTK_BOX (hbox), index_label, TRUE, TRUE, 0);
- tc->index_entry = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(tc->index_entry), "1");
- gtk_box_pack_start (GTK_BOX (hbox), tc->index_entry, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_set_spacing(GTK_BOX(hbox), 10);
- tc->tb_ref_at = gtk_toggle_button_new_with_label("ref_at");
- gtk_box_pack_start (GTK_BOX (hbox), tc->tb_ref_at, TRUE, TRUE, 0);
- row_label = gtk_label_new("row:");
- gtk_box_pack_start (GTK_BOX (hbox), row_label, TRUE, TRUE, 0);
- tc->row_entry = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(tc->row_entry), "1");
- gtk_box_pack_start (GTK_BOX (hbox), tc->row_entry, TRUE, TRUE, 0);
- col_label = gtk_label_new("column:");
- gtk_box_pack_start (GTK_BOX (hbox), col_label, TRUE, TRUE, 0);
- tc->col_entry = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(tc->col_entry), "1");
- gtk_box_pack_start (GTK_BOX (hbox), tc->col_entry, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_set_spacing(GTK_BOX(hbox), 10);
- tc->tb_ref_accessible_child = gtk_toggle_button_new_with_label("ref_accessible_child");
- gtk_box_pack_start (GTK_BOX (hbox), tc->tb_ref_accessible_child, TRUE, TRUE, 0);
- child_label = gtk_label_new("Child no:");
- gtk_box_pack_start (GTK_BOX (hbox), child_label, TRUE, TRUE, 0);
- tc->child_entry = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(tc->child_entry), "1");
- gtk_box_pack_start (GTK_BOX (hbox), tc->child_entry, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
-
- tc->tb_others = gtk_toggle_button_new_with_label("others");
- gtk_box_pack_start (GTK_BOX (vbox), tc->tb_others, TRUE, TRUE, 0);
-
- hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_start (GTK_BOX (vbox), hseparator, TRUE, TRUE, 0);
-
- button = gtk_button_new_with_mnemonic("_Run Test");
-
- hbuttonbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox),
- GTK_BUTTONBOX_SPREAD);
- gtk_box_pack_end (GTK_BOX (hbuttonbox), GTK_WIDGET (button), TRUE, TRUE, 0);
- gtk_box_pack_end (GTK_BOX (vbox), hbuttonbox, TRUE, TRUE, 0);
- g_signal_connect(button, "clicked", G_CALLBACK (choicecb), obj);
-
- gtk_container_add(GTK_CONTAINER(window), vbox);
- gtk_widget_show(vbox);
- gtk_widget_show(window);
- gtk_widget_show_all(GTK_WIDGET(window));
-
- g_visibleGUI = 1;
-}
-
-void static
-nogui_runtest (AtkObject *obj)
-{
- g_print ("Running non-GUI tests...\n");
- other_runtest (obj);
- nogui_ref_at_runtest (obj);
-}
-
-static void
-nogui_ref_at_runtest (AtkObject *obj)
-{
- AtkObject *child_obj;
- gint i, j;
- gint n_cols;
- gint rows_to_loop = 5;
-
- n_cols = atk_table_get_n_columns (ATK_TABLE(obj));
-
- if (atk_table_get_n_rows(ATK_TABLE(obj)) < rows_to_loop)
- rows_to_loop = atk_table_get_n_rows (ATK_TABLE(obj));
-
- for (i=0; i < rows_to_loop; i++)
- {
- /* Just the first rows_to_loop rows */
- for (j=0; j < n_cols; j++)
- {
- gint index = atk_table_get_index_at(ATK_TABLE(obj), i, j);
- if(atk_selection_is_child_selected(ATK_SELECTION(obj), index))
- g_print("atk_selection_is_child_selected,index = %d returns TRUE\n", index);
-
- g_print("Testing ref_at row %d column %d\n", i, j);
-
- if (i == 3 && j == 0)
- {
- g_print("child_obj gotten from atk_selection_ref_selection\n");
-
- /* use atk_selection_ref_selection just once to check it works */
- child_obj = atk_selection_ref_selection(ATK_SELECTION(obj), index );
- }
- else
- {
- child_obj = atk_table_ref_at(ATK_TABLE(obj), i, j);
- }
-
- _property_signal_connect(child_obj);
-
- g_print("Index is %d, row is %d, col is %d\n", index,
- atk_table_get_row_at_index(ATK_TABLE(obj), index),
- atk_table_get_column_at_index(ATK_TABLE(obj), index));
-
- nogui_process_child (child_obj);
-
- /* Generic cell tests */
- /* Just test setting column headers once. */
-
- if (!tested_set_headers)
- {
- tested_set_headers = TRUE;
-
- g_print("Testing set_column_header for column %d, to cell value %d,%d\n",
- j, i, j);
- atk_table_set_column_header(ATK_TABLE(obj), j, child_obj);
-
- g_print("Testing set_row_header for row %d, to cell value %d,%d\n",
- i, i, j);
- atk_table_set_row_header(ATK_TABLE(obj), i, child_obj);
- }
- if (child_obj)
- g_object_unref (child_obj);
- }
- }
-}
-
-static void
-nogui_process_child (AtkObject *obj)
-{
- gchar default_val[5] = "NULL";
-
- if (ATK_IS_TEXT(obj))
- {
- gchar *current_text;
- current_text = atk_text_get_text (ATK_TEXT(obj), 0, -1);
- g_print ("Child supports text interface.\nCurrent text is %s\n", current_text);
- }
-
- if (ATK_IS_ACTION(obj))
- {
- AtkAction *action = ATK_ACTION(obj);
- gint n_actions, i;
- const gchar *name, *description;
-
- n_actions = atk_action_get_n_actions (action);
- g_print ("Child supports %d actions.\n", n_actions);
- for (i = 0; i < n_actions; i++)
- {
- name = atk_action_get_name (action, i);
- description = atk_action_get_description (action, i);
-
- if (name == NULL)
- name = default_val;
- if (description == NULL)
- description = default_val;
-
- g_print (" %d: name = <%s>\n", i, name);
- g_print (" description = <%s>\n", description);
- }
- }
-}
-
+++ /dev/null
-#include <atk/atk.h>
-#include "testtextlib.h"
-
-#define NUM_VALID_ROLES 6
-
-static void _create_event_watcher (void);
-static void _check_text (AtkObject *obj);
-void runtest(AtkObject *, gint);
-
-static guint id1 = 0;
-static guint win_count = 0;
-
-static void _check_text (AtkObject *in_obj)
-{
- AtkObject *obj = NULL;
- AtkRole role;
- gchar* title;
- AtkRole valid_roles[NUM_VALID_ROLES];
-
- if (g_getenv("TEST_ACCESSIBLE_DELAY") != NULL)
- {
- int max_cnt = string_to_int(g_getenv("TEST_ACCESSIBLE_DELAY"));
- win_count++;
- if (win_count <= max_cnt)
- return;
- }
-
- /* Set Up */
-
- valid_roles[0] = ATK_ROLE_TEXT;
- valid_roles[1] = ATK_ROLE_LABEL;
- valid_roles[2] = ATK_ROLE_ACCEL_LABEL;
- valid_roles[3] = ATK_ROLE_PASSWORD_TEXT;
- valid_roles[4] = ATK_ROLE_TABLE_CELL;
- valid_roles[5] = ATK_ROLE_PANEL;
-
- /* The following if/else grabs the windows name, or sets title to NULL if none. */
- if (in_obj->name)
- {
- title = in_obj->name;
- }
- else
- {
- GtkWidget *toplevel;
- GtkWidget* widget;
-
- widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (in_obj));
- if (widget == NULL)
- title = NULL;
-
- toplevel = gtk_widget_get_toplevel (widget);
- if (GTK_IS_WINDOW (toplevel))
- title = (gchar *) gtk_window_get_title (GTK_WINDOW (toplevel));
- else
- title = NULL;
- }
- /* If no window name, do nothing */
- if (title == NULL)
- return;
- /*
- * If testtext test program, find obj just by role since only one child
- * with no name
- */
- else if (g_ascii_strncasecmp(title, "testtext", 7) == 0)
- {
- obj = find_object_by_role(in_obj, valid_roles, NUM_VALID_ROLES);
- }
- /*
- * Otherwise, get obj by name and role so you can specify exactly which
- * obj to run tests on
- */
- else
- {
- const gchar *test_accessible_name = g_getenv ("TEST_ACCESSIBLE_NAME");
-
- if (test_accessible_name != NULL)
- {
- obj = find_object_by_accessible_name_and_role(in_obj,
- test_accessible_name, valid_roles, NUM_VALID_ROLES);
- }
- if (obj != NULL)
- {
- if (atk_object_get_role (obj) == ATK_ROLE_PANEL)
- {
- /* Get the child and check whether it is a label */
-
- obj = atk_object_ref_accessible_child (obj, 0);
- g_assert (atk_object_get_role (obj) == ATK_ROLE_LABEL);
- g_object_unref (obj);
- }
- g_print("Found valid name and role in child!\n");
- }
- else
- {
- obj = find_object_by_role(in_obj, valid_roles, NUM_VALID_ROLES - 1);
- if (obj != NULL)
- g_print("Found valid role in child\n");
- }
- }
- if (obj == NULL)
- {
- g_print("Object not found\n");
- return;
- }
- role = atk_object_get_role(obj);
-
- g_print("_check_text - Found role type %s!\n\n", atk_role_get_name (role));
-
- add_handlers(obj);
-
- if (!(isVisibleDialog()))
- setup_gui(obj, runtest);
- atk_remove_focus_tracker (id1);
-}
-
-static void
-_create_event_watcher (void)
-{
- id1 = atk_add_focus_tracker (_check_text);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testtext Module loaded.\n");
- _create_event_watcher();
-
- return 0;
-}
-
-
+++ /dev/null
-#include <string.h>
-#include <stdio.h>
-#include "testtextlib.h"
-
-static AtkAttributeSet *attrib = NULL;
-static char result_string[2][6] = {"FALSE", "TRUE"};
-
-/**
- * setup_gui:
- * @obj: An @AtkObject
- * @test: The callback to be run when the "Run Tests" button
- * in the GUI is clicked.
- *
- * Sets up the GUI windows.
- *
- * Returns: the window number, or -1 if failure.
- **/
-gint setup_gui(AtkObject *obj, TLruntest test)
-{
- gchar *paramnames[MAX_PARAMS];
- gchar *defaults[MAX_PARAMS];
- static OutputWindow *tow = NULL;
- gint window;
-
- if (tow)
- window = create_windows(obj, test, &tow);
- else
- window = create_windows(obj, test, &tow);
-
- if (window == -1)
- return -1;
-
- /* Get Text [at|after|before] Offset Tests */
- paramnames[0] = "offset";
- defaults[0] = "1";
- add_test(window, "atk_text_get_text_after_offset", 1, paramnames, defaults);
- add_test(window, "atk_text_get_text_before_offset", 1, paramnames, defaults);
- add_test(window, "atk_text_get_text_at_offset",1 , paramnames, defaults);
-
- /* Get Character Count Test */
- add_test(window, "atk_text_get_character_count", 0, NULL, NULL);
-
- /* Get Character At Offset Test */
- paramnames[0] = "offset";
- defaults[0] = "1";
- add_test(window, "atk_text_get_character_at_offset", 1, paramnames, defaults);
-
- /* Get Text Test */
- paramnames[0] = "position 1";
- paramnames[1] = "position 2";
- defaults[0] = "0";
- defaults[1] = "5";
- add_test(window, "atk_text_get_text", 2, paramnames, defaults);
-
- /* Caret Tests */
- add_test(window, "atk_text_get_caret_offset", 0, NULL, NULL);
-
- paramnames[0] = "offset";
- defaults[0] = "1";
- add_test(window, "atk_text_set_caret_offset", 1, paramnames, defaults);
-
- /* Selection Tests */
- add_test(window, "atk_text_get_n_selections", 0, NULL, NULL);
-
- paramnames[0] = "selection no";
- defaults[0] = "0";
- add_test(window, "atk_text_get_selection", 1, paramnames, defaults);
-
- paramnames[0] = "start";
- paramnames[1] = "end";
- defaults[0] = "3";
- defaults[1] = "8";
- add_test(window, "atk_text_add_selection", 2, paramnames, defaults);
-
- paramnames[0] = "selection no";
- paramnames[1] = "start";
- paramnames[2] = "end";
- defaults[0] = "0";
- defaults[1] = "5";
- defaults[2] = "7";
- add_test(window, "atk_text_set_selection", 3, paramnames, defaults);
-
- paramnames[0] = "selection no";
- defaults[0] = "0";
- add_test(window, "atk_text_remove_selection", 1, paramnames, defaults);
-
- paramnames[0] = "offset";
- defaults[0] = "36";
- add_test(window, "atk_text_get_run_attributes", 1, paramnames, defaults);
-
- add_test(window, "atk_text_get_default_attributes", 0, paramnames, defaults);
-
- paramnames[0] = "offset";
- paramnames[1] = "coord mode";
- defaults[0] = "0";
- defaults[1] = "ATK_XY_SCREEN";
- add_test(window, "atk_text_get_character_extents", 2, paramnames, defaults);
-
- paramnames[0] = "x";
- paramnames[1] = "y";
- paramnames[2] = "coord mode";
- defaults[0] = "106";
- defaults[1] = "208";
- defaults[2] = "ATK_XY_SCREEN";
- add_test(window, "atk_text_get_offset_at_point", 3, paramnames, defaults);
-
- /* Editable Text Tests */
- if (ATK_IS_EDITABLE_TEXT(obj))
- {
-
- paramnames[0] = "start";
- paramnames[1] = "end";
- defaults[0] = "20";
- defaults[1] = "27";
- add_test(window, "atk_editable_text_set_run_attributes", 2, paramnames, defaults);
-
- paramnames[0] = "start";
- paramnames[1] = "end";
- defaults[0] = "3";
- defaults[1] = "5";
- add_test(window, "atk_editable_text_cut_text", 2, paramnames, defaults);
-
- paramnames[0] = "position";
- defaults[0] = "8";
- add_test(window, "atk_editable_text_paste_text", 1, paramnames, defaults);
-
- paramnames[0] = "start";
- paramnames[1] = "end";
- defaults[0] = "15";
- defaults[1] = "20";
- add_test(window, "atk_editable_text_delete_text", 2, paramnames, defaults);
- paramnames[0] = "start";
- paramnames[1] = "end";
- defaults[0] = "5";
- defaults[1] = "20";
- add_test(window, "atk_editable_text_copy_text", 2, paramnames, defaults);
-
- paramnames[0] = "insert text";
- paramnames[1] = "position";
- defaults[0] = "this is my insert";
- defaults[1] = "15";
- add_test(window, "atk_editable_text_insert_text", 2, paramnames, defaults);
- }
- return window;
-}
-
-/**
- * add_handlers:
- * @obj: An #AtkObject
- *
- * Sets up text signal handlers.
- *
- **/
-void add_handlers(AtkObject *obj)
-{
- if (!already_accessed_atk_object(obj))
- {
- /* Set up signal handlers */
-
- g_print ("Adding signal handler\n");
- g_signal_connect_closure_by_id (obj,
- g_signal_lookup ("text_caret_moved", G_OBJECT_TYPE (obj)),
- 0,
- g_cclosure_new (G_CALLBACK (_notify_caret_handler),
- NULL, NULL),
- FALSE);
-
- g_signal_connect_closure (obj, "text_changed::insert",
- g_cclosure_new (G_CALLBACK (_notify_text_insert_handler),
- NULL, NULL),
- FALSE);
-
- g_signal_connect_closure (obj, "text_changed::delete",
- g_cclosure_new (G_CALLBACK (_notify_text_delete_handler),
- NULL, NULL),
- FALSE);
- }
-}
-
-/**
- * notify_text_insert_handler:
- * @obj: A #Gobject
- * @start_offset: Start offset of insert
- * @end_offset: End offset of insert.
- *
- * Text inserted singal handler
- **/
-void
-_notify_text_insert_handler (GObject *obj, int start_offset, int end_offset)
-{
- g_print ("SIGNAL - Text inserted at position %d, length %d!\n",
- start_offset, end_offset);
-}
-
-/**
- * notify_text_delete_handler:
- * @obj: A #Gobject
- * @start_offset: Start offset of delete
- * @end_offset: End offset of delete.
- *
- * Text deleted singal handler
- **/
-void
-_notify_text_delete_handler (GObject *obj, int start_offset, int end_offset)
-{
- g_print ("SIGNAL - Text deleted at position %d, length %d!\n",
- start_offset, end_offset);
-}
-
-/**
- * notify_caret_handler:
- * @obj: A #Gobject
- * @position: Caret position
- *
- * Caret (cursor) moved signal handler.
- **/
-void
-_notify_caret_handler (GObject *obj, int position)
-{
- g_print ("SIGNAL - The caret moved to position %d!\n", position);
-}
-
-/**
- * runtest:
- * @obj: An #AtkObject
- * @win_val: The window number
- *
- * The callback to run when the "Run Tests" button on the
- * Test GUI is clicked.
- **/
-void
-runtest(AtkObject *obj, gint win_val)
-{
- gint i, size;
- gunichar uni_char;
- gchar output[MAX_LINE_SIZE];
- gchar **testsOn;
-
- testsOn = tests_set(win_val, &size);
-
- for(i = 0; i < size; i++)
- {
- gint param_int1, param_int2, start, end, j, x, y, height, width;
- gchar *param_string1, *param_string2, *param_string3, *text;
- gboolean result;
- gint index;
-
- if (strcmp(testsOn[i], "atk_text_get_text_at_offset") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_get_text_at_offset", "offset");
- param_int1 = string_to_int(param_string1);
-
- _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_WORD_END);
- _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_WORD_START);
- _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_LINE_END);
- _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_LINE_START);
- _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_END);
- _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_START);
- _run_offset_test(obj, "at", param_int1, ATK_TEXT_BOUNDARY_CHAR);
- }
-
- if (strcmp(testsOn[i], "atk_text_get_text_after_offset") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_get_text_after_offset", "offset");
- param_int1 = string_to_int(param_string1);
-
- _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_WORD_END);
- _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_WORD_START);
- _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_LINE_END);
- _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_LINE_START);
- _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_END);
- _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_START);
- _run_offset_test(obj, "after", param_int1, ATK_TEXT_BOUNDARY_CHAR);
- }
-
- if (strcmp(testsOn[i], "atk_text_get_text_before_offset") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_get_text_before_offset", "offset");
- param_int1 = string_to_int(param_string1);
-
- _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_WORD_END);
- _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_WORD_START);
- _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_LINE_END);
- _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_LINE_START);
- _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_END);
- _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_SENTENCE_START);
- _run_offset_test(obj, "before", param_int1, ATK_TEXT_BOUNDARY_CHAR);
- }
-
- if (strcmp(testsOn[i], "atk_text_get_character_count") == 0)
- {
- param_int1 = atk_text_get_character_count (ATK_TEXT (obj));
- sprintf(output, "\nText character count: %d\n", param_int1);
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_text_get_character_at_offset") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_get_character_at_offset",
- "offset");
- uni_char = atk_text_get_character_at_offset (ATK_TEXT(obj),
- string_to_int(param_string1));
- sprintf(output, "\nCharacter at offset %d: |%x|\n",
- string_to_int(param_string1), uni_char);
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_text_get_text") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_get_text", "position 1");
- param_string2 = get_arg_of_func(win_val, "atk_text_get_text", "position 2");
- text = atk_text_get_text (ATK_TEXT (obj), string_to_int(param_string1),
- string_to_int(param_string2));
- sprintf(output, "\nText %d, %d: %s\n", string_to_int(param_string1),
- string_to_int(param_string2), text);
- g_free (text);
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_text_get_caret_offset") == 0)
- {
- param_int1 = atk_text_get_caret_offset (ATK_TEXT (obj));
- if (param_int1 == -1)
- sprintf(output, "\nCaret offset: |Not Supported|\n");
- else
- sprintf(output, "\nCaret offset: %d\n", param_int1);
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_text_set_caret_offset") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_set_caret_offset", "offset");
- atk_text_set_caret_offset(ATK_TEXT(obj), string_to_int(param_string1));
- sprintf(output, "\nPutting caret at offset: |%d|\n",
- string_to_int(param_string1));
- param_int1 = atk_text_get_caret_offset (ATK_TEXT (obj));
-
- if (param_int1 == -1)
- sprintf(output, "\nCaret offset: |Not Supported|\n");
- else
- sprintf(output, "\nCaret offset was set at: |%d|\n", param_int1);
-
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_text_get_n_selections") == 0)
- {
- param_int1 = atk_text_get_n_selections(ATK_TEXT(obj));
- if (param_int1 == -1)
- {
- sprintf(output, "\nNo selected regions\n");
- set_output_buffer(output);
- }
-
- for (j = 0; j < param_int1; j++)
- {
- sprintf(output, "\nNumber of selected text regions is: |%d|\n", j);
- set_output_buffer(output);
-
- text = atk_text_get_selection(ATK_TEXT(obj), j, &start, &end);
- if (text != NULL)
- {
- sprintf(output, "\nSelected text for region %d is: |%s|\n", j, text);
- set_output_buffer(output);
- sprintf(output,
- "\nStart selection bounds: %d\tEnd selection bounds: %d\n",
- start, end);
- }
- else
- {
- sprintf(output, "\nNo selected region %d\n", j);
- }
-
- set_output_buffer(output);
- }
- }
-
- if (strcmp(testsOn[i], "atk_text_add_selection") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_add_selection", "start");
- param_string2 = get_arg_of_func(win_val, "atk_text_add_selection", "end");
- result = atk_text_add_selection(ATK_TEXT(obj),
- string_to_int(param_string1), string_to_int(param_string2));
- sprintf(output, "\nSet selection bounds between %d, and %d: %s",
- string_to_int(param_string1), string_to_int(param_string2),
- result_string[result]);
- set_output_buffer(output);
-
- param_int1 = atk_text_get_n_selections(ATK_TEXT(obj));
- for (j = 0; j < param_int1; j++)
- {
- sprintf(output, "\nNumber of selected text region is: %d\n", j);
- set_output_buffer(output);
- text = atk_text_get_selection(ATK_TEXT(obj), j, &start, &end);
-
- if (text != NULL)
- {
- sprintf(output, "\nSelected text for region %d is: |%s|\n", j, text);
- set_output_buffer(output);
- sprintf(output,
- "\nStart selection bounds: %d\tEnd selection bounds: %d\n",
- start, end);
- }
- else
- {
- sprintf(output, "\nNo selected region %d\n", j);
- }
-
- set_output_buffer(output);
- }
- }
-
- if (strcmp(testsOn[i], "atk_text_get_selection") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_get_selection", "selection no");
- text = atk_text_get_selection(ATK_TEXT(obj),
- string_to_int(param_string1), &start, &end);
-
- if (text != NULL)
- {
- sprintf(output, "\nSelected text for region %d is: |%s|\n",
- string_to_int(param_string1), text);
- set_output_buffer(output);
- sprintf(output,
- "\nStart selection bounds: %d\t End selection bounds: %d\n",
- start, end);
- }
- else
- {
- sprintf(output, "\nNo selected region %d\n", string_to_int(param_string1));
- }
-
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_text_set_selection") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_set_selection", "selection no");
- param_string2 = get_arg_of_func(win_val, "atk_text_set_selection", "start");
- param_string3 = get_arg_of_func(win_val, "atk_text_set_selection", "end");
- result = atk_text_set_selection(ATK_TEXT(obj), string_to_int(param_string1),
- string_to_int(param_string2), string_to_int(param_string3));
- sprintf(output, "Set selection %d's bounds between %d and %d: %s\n",
- string_to_int(param_string1), string_to_int(param_string2),
- string_to_int(param_string3), result_string[result]);
- set_output_buffer(output);
- text = atk_text_get_selection(ATK_TEXT(obj), string_to_int(param_string1),
- &start, &end);
-
- if (text != NULL)
- {
- sprintf(output, "Selected text for the reset region %d is: |%s|\n",
- string_to_int(param_string1), text);
- set_output_buffer(output);
- sprintf(output,
- "\nNew start selection bounds: %d\tNew end selection bounds: %d\n",
- start, end);
- }
- else
- {
- sprintf(output, "\nNo selected region %d\n", string_to_int(param_string1));
- }
-
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_text_remove_selection") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_text_remove_selection", "selection no");
- result = atk_text_remove_selection(ATK_TEXT(obj), string_to_int(param_string1));
- sprintf(output, "Remove selection for region %d: %s\n",
- string_to_int(param_string1), result_string[result]);
- set_output_buffer(output);
- text = atk_text_get_selection(ATK_TEXT(obj),
- string_to_int(param_string1), &start, &end);
-
- if (text != NULL)
- sprintf(output, "\nRemoved regions text should be empty instead of: %s", text);
- else
- sprintf(output, "\nRemoved regions text should be empty, this is: ||");
-
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_text_get_run_attributes") == 0)
- {
- gint test_int;
- param_string1 = get_arg_of_func(win_val, "atk_text_get_run_attributes", "offset");
- test_int = string_to_int(param_string1);
- attrib = atk_text_get_run_attributes(ATK_TEXT(obj), test_int, &start, &end);
- sprintf(output, "get_run_attributes at offset %i:\nStart: %i, End: %i\n", test_int,
- start, end);
- set_output_buffer(output);
- if (attrib != NULL) {
- GSList *node;
- index = 0;
- node = attrib;
- while (node != NULL)
- {
- AtkAttribute* att = node->data;
-
- sprintf(output, "List index: %i, Name: %s, Value: %s\n", index,
- att->name, att->value);
- set_output_buffer(output);
- node = node->next;
- index++;
- }
- atk_attribute_set_free (attrib);
- }
- }
-
- if (strcmp(testsOn[i], "atk_text_get_default_attributes") == 0)
- {
- attrib = atk_text_get_default_attributes(ATK_TEXT(obj));
- sprintf(output, "get_default_attributes\n");
- set_output_buffer(output);
- if (attrib != NULL) {
- GSList *node;
- index = 0;
- node = attrib;
- while (node != NULL)
- {
- AtkAttribute* att = node->data;
-
- sprintf(output, "List index: %i, Name: %s, Value: %s\n", index,
- att->name, att->value);
- set_output_buffer(output);
- node = node->next;
- index++;
- }
- atk_attribute_set_free (attrib);
- }
- }
-
- if (strcmp(testsOn[i], "atk_text_get_character_extents") == 0)
- {
- gint test_int;
- param_string1 = get_arg_of_func(win_val, "atk_text_get_character_extents",
- "offset");
- param_string2 = get_arg_of_func(win_val, "atk_text_get_character_extents",
- "coord mode");
- test_int = string_to_int(param_string1);
- if (strcmp(param_string2, "ATK_XY_SCREEN") == 0)
- {
- atk_text_get_character_extents(ATK_TEXT(obj), test_int, &x, &y, &width,
- &height, ATK_XY_SCREEN);
- sprintf(output,
- "get_character_extents at offset %i, mode: SCREEN\nX: %i, Y: %i, width: %i, height: %i\n",
- test_int, x, y, width, height);
- }
- else if (strcmp(param_string2, "ATK_XY_WINDOW") == 0)
- {
- atk_text_get_character_extents(ATK_TEXT(obj), test_int, &x, &y, &width,
- &height, ATK_XY_WINDOW);
- sprintf(output,
- "get_character_extents at offset %i, mode: WIDGET_WINDOW\nX: %i, Y: %i, width: %i, height: %i\n",
- test_int, x, y, width, height);
- }
- else
- sprintf(output, "get_character_extents_at_offset: Invalid coord mode argument!");
-
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_text_get_offset_at_point") == 0)
- {
- gint test_int;
- param_string1 = get_arg_of_func(win_val, "atk_text_get_offset_at_point", "x");
- param_string2 = get_arg_of_func(win_val, "atk_text_get_offset_at_point", "y");
- param_string3 = get_arg_of_func(win_val, "atk_text_get_offset_at_point", "coord mode");
- param_int1 = string_to_int(param_string1);
- param_int2 = string_to_int(param_string2);
- if (strcmp(param_string3, "ATK_XY_SCREEN") == 0)
- {
- test_int = atk_text_get_offset_at_point(ATK_TEXT(obj), param_int1, param_int2,
- ATK_XY_SCREEN);
- if (test_int != -1)
- sprintf(output, "get_offset_at_point %i,%i mode: SCREEN is %i\n", param_int1, param_int2, test_int);
- else
- sprintf(output, "Cannot get_offset_at_point\n");
- }
- else if (strcmp(param_string3, "ATK_XY_WINDOW") == 0)
- {
- test_int = atk_text_get_offset_at_point(ATK_TEXT(obj), param_int1, param_int2,
- ATK_XY_WINDOW);
- if (test_int != -1)
- sprintf(output, "get_offset_at_point %i,%i mode: WIDGET_WINDOW is %i\n", param_int1, param_int2, test_int);
- else
- sprintf(output, "Cannot get_offset_at_point\n");
- }
- else
- sprintf(output, "get_offset_at_point: Invalid coord mode argument!");
-
- set_output_buffer(output);
- }
- if (ATK_IS_EDITABLE_TEXT(obj))
- {
- if (strcmp(testsOn[i], "atk_editable_text_set_run_attributes") == 0)
- {
- param_string1 = get_arg_of_func(win_val,
- "atk_editable_text_set_run_attributes", "start");
- param_string2 = get_arg_of_func(win_val,
- "atk_editable_text_set_run_attributes", "end");
- result = atk_editable_text_set_run_attributes(ATK_EDITABLE_TEXT(obj),
- attrib, string_to_int(param_string1), string_to_int(param_string2));
- if (result)
- sprintf(output, "\nSetting attributes in range %d to %d...OK\n",
- string_to_int(param_string1), string_to_int(param_string2));
- else
- sprintf(output, "\nSetting attributes in range %d to %d...Failed\n",
- string_to_int(param_string1), string_to_int(param_string2));
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_editable_text_cut_text") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_editable_text_cut_text", "start");
- param_string2 = get_arg_of_func(win_val, "atk_editable_text_cut_text", "end");
- atk_editable_text_cut_text(ATK_EDITABLE_TEXT(obj),
- string_to_int(param_string1), string_to_int(param_string2));
- sprintf(output, "\nCutting text %d to %d...\n",
- string_to_int(param_string1), string_to_int(param_string2));
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_editable_text_paste_text") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_editable_text_paste_text",
- "position");
- atk_editable_text_paste_text(ATK_EDITABLE_TEXT(obj),
- string_to_int(param_string1));
- sprintf(output, "\nPasting text to %d\n", string_to_int(param_string1));
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_editable_text_delete_text") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_editable_text_delete_text", "start");
- param_string2 = get_arg_of_func(win_val, "atk_editable_text_delete_text", "end");
- atk_editable_text_delete_text(ATK_EDITABLE_TEXT(obj),
- string_to_int(param_string1), string_to_int(param_string2));
- sprintf(output, "\nDeleting text %d to %d...\n",
- string_to_int(param_string1), string_to_int(param_string2));
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_editable_text_copy_text") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_editable_text_copy_text", "start");
- param_string2 = get_arg_of_func(win_val, "atk_editable_text_copy_text", "end");
- atk_editable_text_copy_text(ATK_EDITABLE_TEXT(obj),
- string_to_int(param_string1), string_to_int(param_string2));
- sprintf(output, "\nCopying text %d to %d...\n",
- string_to_int(param_string1), string_to_int(param_string2));
- set_output_buffer(output);
- }
-
- if (strcmp(testsOn[i], "atk_editable_text_insert_text") == 0)
- {
- param_string1 = get_arg_of_func(win_val, "atk_editable_text_insert_text",
- "insert text");
- param_string2 = get_arg_of_func(win_val, "atk_editable_text_insert_text",
- "position");
- param_int2 = string_to_int(param_string2);
- atk_editable_text_insert_text(ATK_EDITABLE_TEXT(obj),
- param_string1, strlen(param_string1), ¶m_int2);
- sprintf(output, "\nInserting text at %d...\n", param_int2);
- set_output_buffer(output);
- }
- }
- }
-}
-
-/**
- * _run_offset_test:
- * @obj: An #AtkObject
- * @type: The type of test to run. Can be "at", "before", or "after".
- * @offset: The offset into the text buffer.
- * @boundary: The boundary type.
- *
- * Tests the following ATK_TEXT API functions:
- * atk_text_get_text_at_offset
- * atk_text_get_text_before_offseet
- * atk_text_get_text_after_offset
- **/
-void _run_offset_test(AtkObject * obj, char * type, gint offset,
- AtkTextBoundary boundary)
-{
- gchar output[MAX_LINE_SIZE];
- gchar default_val[5] = "NULL";
- gchar *text;
- gint startOffset, endOffset;
-
- if (strcmp(type, "at") == 0)
- text = atk_text_get_text_at_offset (ATK_TEXT (obj),
- offset, boundary, &startOffset, &endOffset);
- else if (strcmp(type, "before") == 0)
- text = atk_text_get_text_before_offset (ATK_TEXT (obj),
- offset, boundary, &startOffset, &endOffset);
- else if (strcmp(type, "after") == 0)
- text = atk_text_get_text_after_offset (ATK_TEXT (obj),
- offset, boundary, &startOffset, &endOffset);
- else
- text = NULL;
-
- if (text == NULL)
- text = g_strdup (default_val);
-
- if (boundary == ATK_TEXT_BOUNDARY_CHAR)
- sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_CHAR|\n",
- type, text);
- else if (boundary == ATK_TEXT_BOUNDARY_WORD_START)
- sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_WORD_START|\n",
- type, text);
- else if (boundary == ATK_TEXT_BOUNDARY_WORD_END)
- sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_WORD_END|\n",
- type, text);
- else if (boundary == ATK_TEXT_BOUNDARY_SENTENCE_START)
- sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_SENTENCE_START|\n",
- type, text);
- else if (boundary == ATK_TEXT_BOUNDARY_SENTENCE_END)
- sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_SENTENCE_END|\n",
- type, text);
- else if (boundary == ATK_TEXT_BOUNDARY_LINE_START)
- sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_LINE_START|\n",
- type, text);
- else if (boundary == ATK_TEXT_BOUNDARY_LINE_END)
- sprintf(output, "\n|%s| Text |%s| Boundary |BOUNDARY_LINE_END|\n",
- type, text);
- else
- sprintf(output, "\n|%s| Text |%s| Boundary |UNKNOWN|\n",
- type, text);
-
- g_free (text);
- set_output_buffer(output);
-
- sprintf(output, "Offset %d, startOffset %d, endOffset %d\n",
- offset, startOffset, endOffset);
- set_output_buffer(output);
-}
+++ /dev/null
-#include <stdio.h>
-#include <gtk/gtk.h>
-#include <atk/atk.h>
-#include "testlib.h"
-
-void add_handlers (AtkObject *obj);
-gint setup_gui (AtkObject *obj, TLruntest test);
-void runtest(AtkObject *obj, gint win_num);
-void _run_offset_test(AtkObject *obj, char * type, gint param_int1, AtkTextBoundary boundary);
-void _notify_caret_handler (GObject *obj, int position);
-void _notify_text_insert_handler (GObject *obj,
- int start_offset, int end_offset);
-void _notify_text_delete_handler (GObject *obj,
- int start_offset, int end_offset);
-
+++ /dev/null
-#include <atk/atk.h>
-#include <gtk/gtk.h>
-#include "testlib.h"
-
-static void _notify_toplevel_child_added (GObject *obj,
- guint index, AtkObject *child, gpointer user_data);
-static void _notify_toplevel_child_removed (GObject *obj,
- guint index, AtkObject *child, gpointer user_data);
-static gboolean _button_press_event_watcher (GSignalInvocationHint *ihint,
- guint n_param_values, const GValue *param_values, gpointer data);
-
-static guint id;
-static gboolean g_register_listener = FALSE;
-static guint g_signal_listener = 0;
-static gint g_press_count = 0;
-
-static void
-_check_toplevel (AtkObject *obj)
-{
- AtkObject *root_obj;
- const gchar *name_string, *version_string;
- gint max_depth;
-
- g_print ("Start of _check_toplevel\n");
- root_obj = atk_get_root();
-
- if (!already_accessed_atk_object(root_obj))
- {
- g_signal_connect_closure (root_obj, "children_changed::add",
- g_cclosure_new (G_CALLBACK (_notify_toplevel_child_added),
- NULL, NULL),
- FALSE);
-
- g_signal_connect_closure (root_obj, "children_changed::remove",
- g_cclosure_new (G_CALLBACK (_notify_toplevel_child_removed),
- NULL, NULL),
- FALSE);
- }
-
- name_string = atk_get_toolkit_name();
- version_string = atk_get_toolkit_version();
- g_print ("Toolkit name <%s> version <%s>\n", name_string,
- version_string);
-
- if (g_getenv("TEST_ACCESSIBLE_DEPTH") != NULL)
- max_depth = string_to_int(g_getenv("TEST_ACCESSIBLE_DEPTH"));
- else
- max_depth = 2;
-
- display_children_to_depth(root_obj, max_depth, 0, 0);
- g_print ("End of _check_toplevel\n");
-
- if (!g_register_listener)
- {
- g_print("Adding global event listener on buttons\n");
- g_register_listener = TRUE;
- g_signal_listener = atk_add_global_event_listener(_button_press_event_watcher,
- "Gtk:GtkButton:pressed");
- }
-}
-
-static void
-_create_event_watcher (void)
-{
- id = atk_add_focus_tracker (_check_toplevel);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testtoplevel Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}
-
-static void _notify_toplevel_child_added (GObject *obj,
- guint child_index, AtkObject *child, gpointer user_data)
-{
- g_print ("SIGNAL - Child added - index %d\n", child_index);
-}
-
-static void _notify_toplevel_child_removed (GObject *obj,
- guint child_index, AtkObject *child, gpointer user_data)
-{
- g_print ("SIGNAL - Child removed - index %d\n", child_index);
-}
-
-static gboolean
-_button_press_event_watcher (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- gchar * button_name = (gchar *) data;
-
- object = g_value_get_object (param_values + 0);
-
- if (ATK_IS_IMPLEMENTOR(object))
- {
- AtkObject * atk_obj =
- atk_implementor_ref_accessible(ATK_IMPLEMENTOR(object));
-
- g_print("Button <%s> pressed %d times!\n", button_name,
- (g_press_count + 1));
- g_print("Displaying children of Button pressed!\n");
- display_children(atk_obj, 0, 0);
-
- if (g_press_count >= 5)
- {
- g_print("Removing global event listener on buttons\n");
- atk_remove_global_event_listener(g_signal_listener);
- g_signal_listener = 0;
- g_press_count = 0;
- g_register_listener = FALSE;
- }
- else
- {
- g_press_count++;
- }
- }
-
- return TRUE;
-}
-
+++ /dev/null
-#include <stdlib.h>
-#include <testlib.h>
-
-/*
- * This module is for use with the test program testtreeview
- */
-static gboolean state_change_watch (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data);
-
-static void _check_table (AtkObject *in_obj);
-static void _check_cell_actions (AtkObject *in_obj);
-
-static gint _find_expander_column (AtkTable *table);
-static void _check_expanders (AtkTable *table,
- gint expander_column);
-static void _runtest (AtkObject *obj);
-static void _create_event_watcher (void);
-static void row_inserted (AtkObject *obj,
- gint row,
- gint count);
-static void row_deleted (AtkObject *obj,
- gint row,
- gint count);
-static AtkObject *table_obj = NULL;
-static gint expander_column = -1;
-static gboolean editing_cell = FALSE;
-
-static gboolean
-state_change_watch (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GObject *object;
- gboolean state_set;
- const gchar *state_name;
- AtkStateType state_type;
-
- object = g_value_get_object (param_values + 0);
- g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
-
- state_name = g_value_get_string (param_values + 1);
- state_set = g_value_get_boolean (param_values + 2);
-
- g_print ("Object type: %s state: %s set: %d\n",
- g_type_name (G_OBJECT_TYPE (object)), state_name, state_set);
- state_type = atk_state_type_for_name (state_name);
- if (state_type == ATK_STATE_EXPANDED)
- {
- AtkObject *parent = atk_object_get_parent (ATK_OBJECT (object));
-
- if (ATK_IS_TABLE (parent))
- _check_expanders (ATK_TABLE (parent), expander_column);
- }
- return TRUE;
-}
-
-static void
-_check_table (AtkObject *in_obj)
-{
- AtkObject *obj;
- AtkRole role[2];
- AtkRole obj_role;
- static gboolean emission_hook_added = FALSE;
-
- if (!emission_hook_added)
- {
- emission_hook_added = TRUE;
- g_signal_add_emission_hook (
- g_signal_lookup ("state-change", ATK_TYPE_OBJECT),
- /*
- * To specify an emission hook for a particular state, e.g.
- * ATK_STATE_EXPANDED, instead of 0 use
- * g_quark_from_string (atk_state_type_get_name (ATK_STATE_EXPANDED))
- */
- 0,
- state_change_watch, NULL, (GDestroyNotify) NULL);
- }
-
- role[0] = ATK_ROLE_TABLE;
- role[1] = ATK_ROLE_TREE_TABLE;
-
- g_print ("focus event for: %s\n", g_type_name (G_OBJECT_TYPE (in_obj)));
-
- _check_cell_actions (in_obj);
-
- obj_role = atk_object_get_role (in_obj);
- if (obj_role == ATK_ROLE_TABLE_CELL)
- obj = atk_object_get_parent (in_obj);
- else
- obj = find_object_by_role (in_obj, role, 2);
- if (obj == NULL)
- return;
-
- editing_cell = FALSE;
-
- if (obj != table_obj)
- {
- table_obj = obj;
- g_print("Found %s table\n", g_type_name (G_OBJECT_TYPE (obj)));
- g_signal_connect (G_OBJECT (obj),
- "row_inserted",
- G_CALLBACK (row_inserted),
- NULL);
- g_signal_connect (G_OBJECT (obj),
- "row_deleted",
- G_CALLBACK (row_deleted),
- NULL);
- /*
- * Find expander column
- */
- if (ATK_IS_TABLE (obj))
- {
- if (atk_object_get_role (obj) == ATK_ROLE_TREE_TABLE)
- {
- expander_column = _find_expander_column (ATK_TABLE (obj));
- if (expander_column == -1)
- {
- g_warning ("Expander column not found\n");
- return;
- }
- }
- _runtest(obj);
- }
- else
- g_warning ("Table does not support AtkTable interface\n");
- }
- else
- {
- /*
- * We do not call these functions at the same time as we set the
- * signals as the GtkTreeView may not be displayed yet.
- */
- gint x, y, width, height, first_x, last_x, last_y;
- gint first_row, last_row, first_column, last_column;
- gint index;
- AtkObject *first_child, *last_child, *header;
- AtkComponent *component = ATK_COMPONENT (obj);
- AtkTable *table = ATK_TABLE (obj);
-
- atk_component_get_extents (component,
- &x, &y, &width, &height, ATK_XY_WINDOW);
- g_print ("WINDOW: x: %d y: %d width: %d height: %d\n",
- x, y, width, height);
- atk_component_get_extents (component,
- &x, &y, &width, &height, ATK_XY_SCREEN);
- g_print ("SCREEN: x: %d y: %d width: %d height: %d\n",
- x, y, width, height);
- last_x = x + width - 1;
- last_y = y + height - 1;
- first_x = x;
- header = atk_table_get_column_header (table, 0);
- if (header)
- {
- atk_component_get_extents (ATK_COMPONENT (header),
- &x, &y, &width, &height, ATK_XY_SCREEN);
- g_print ("Got column header: x: %d y: %d width: %d height: %d\n",
- x, y, width, height);
- y += height;
- }
- first_child = atk_component_ref_accessible_at_point (component,
- first_x, y, ATK_XY_SCREEN);
- atk_component_get_extents (ATK_COMPONENT (first_child),
- &x, &y, &width, &height, ATK_XY_SCREEN);
- g_print ("first_child: x: %d y: %d width: %d height: %d\n",
- x, y, width, height);
- index = atk_object_get_index_in_parent (ATK_OBJECT (first_child));
- first_row = atk_table_get_row_at_index (table, index);
- first_column = atk_table_get_column_at_index (table, index);
- g_print ("first_row: %d first_column: %d index: %d\n",
- first_row, first_column, index);
- g_assert (index == atk_table_get_index_at (table, first_row, first_column));
- last_child = atk_component_ref_accessible_at_point (component,
- last_x, last_y, ATK_XY_SCREEN);
- if (last_child == NULL)
- {
- /* The TreeView may be bigger than the data */
- gint n_children;
-
- n_children = atk_object_get_n_accessible_children (obj);
- last_child = atk_object_ref_accessible_child (obj, n_children - 1);
- }
- atk_component_get_extents (ATK_COMPONENT (last_child),
- &x, &y, &width, &height, ATK_XY_SCREEN);
- g_print ("last_child: x: %d y: %d width: %d height: %d\n",
- x, y, width, height);
- index = atk_object_get_index_in_parent (ATK_OBJECT (last_child));
- last_row = atk_table_get_row_at_index (table, index);
- last_column = atk_table_get_column_at_index (table, index);
- g_print ("last_row: %d last_column: %d index: %d\n",
- last_row, last_column, index);
- g_assert (index == atk_table_get_index_at (table, last_row, last_column));
- g_object_unref (first_child);
- g_object_unref (last_child);
-
- if (expander_column >= 0)
- {
- gint n_rows, i;
- gint x, y, width, height;
-
- n_rows = atk_table_get_n_rows (table);
- for (i = 0; i < n_rows; i++)
- {
- AtkObject *child_obj;
- AtkStateSet *state_set;
- gboolean showing;
-
- child_obj = atk_table_ref_at (table, i, expander_column);
- state_set = atk_object_ref_state_set (child_obj);
- showing = atk_state_set_contains_state (state_set,
- ATK_STATE_SHOWING);
- g_object_unref (state_set);
- atk_component_get_extents (ATK_COMPONENT (child_obj),
- &x, &y, &width, &height,
- ATK_XY_SCREEN);
- g_object_unref (child_obj);
- if (showing)
- g_print ("Row: %d Column: %d x: %d y: %d width: %d height: %d\n",
- i, expander_column, x, y, width, height);
- }
- }
- }
-}
-
-static void
-_check_cell_actions (AtkObject *in_obj)
-{
- AtkRole role;
- AtkAction *action;
- gint n_actions, i;
-
- role = atk_object_get_role (in_obj);
- if (role != ATK_ROLE_TABLE_CELL)
- return;
-
- if (!ATK_IS_ACTION (in_obj))
- return;
-
- if (editing_cell)
- return;
-
- action = ATK_ACTION (in_obj);
-
- n_actions = atk_action_get_n_actions (action);
-
- for (i = 0; i < n_actions; i++)
- {
- const gchar* name;
-
- name = atk_action_get_name (action, i);
- g_print ("Action %d is %s\n", i, name);
-#if 0
- if (strcmp (name, "edit") == 0)
- {
- editing_cell = TRUE;
- atk_action_do_action (action, i);
- }
-#endif
- }
- return;
-}
-
-static gint
-_find_expander_column (AtkTable *table)
-{
- gint n_columns, i;
- gint retval = -1;
-
- n_columns = atk_table_get_n_columns (table);
- for (i = 0; i < n_columns; i++)
- {
- AtkObject *cell;
- AtkRelationSet *relation_set;
-
- cell = atk_table_ref_at (table, 0, i);
- relation_set = atk_object_ref_relation_set (cell);
- if (atk_relation_set_contains (relation_set,
- ATK_RELATION_NODE_CHILD_OF))
- retval = i;
- g_object_unref (relation_set);
- g_object_unref (cell);
- if (retval >= 0)
- break;
- }
- return retval;
-}
-
-static void
-_check_expanders (AtkTable *table,
- gint expander_column)
-{
- gint n_rows, i;
-
- n_rows = atk_table_get_n_rows (table);
-
- for (i = 0; i < n_rows; i++)
- {
- AtkObject *cell;
- AtkRelationSet *relation_set;
- AtkRelation *relation;
- GPtrArray *target;
- gint j;
-
- cell = atk_table_ref_at (table, i, expander_column);
-
- relation_set = atk_object_ref_relation_set (cell);
- relation = atk_relation_set_get_relation_by_type (relation_set,
- ATK_RELATION_NODE_CHILD_OF);
- g_assert (relation);
- target = atk_relation_get_target (relation);
- g_assert (target->len == 1);
- for (j = 0; j < target->len; j++)
- {
- AtkObject *target_obj;
- AtkRole role;
- gint target_index, target_row;
-
- target_obj = g_ptr_array_index (target, j);
- role = atk_object_get_role (target_obj);
-
- switch (role)
- {
- case ATK_ROLE_TREE_TABLE:
- g_print ("Row %d is top level\n", i);
- break;
- case ATK_ROLE_TABLE_CELL:
- target_index = atk_object_get_index_in_parent (target_obj);
- target_row = atk_table_get_row_at_index (table, target_index);
- g_print ("Row %d has parent at %d\n", i, target_row);
- break;
- default:
- g_assert_not_reached ();
- }
- }
- g_object_unref (relation_set);
- g_object_unref (cell);
- }
-}
-
-static void
-_create_event_watcher (void)
-{
- atk_add_focus_tracker (_check_table);
-}
-
-int
-gtk_module_init (gint argc,
- char *argv[])
-{
- g_print ("testtreetable Module loaded\n");
-
- _create_event_watcher ();
-
- return 0;
-}
-
-static void
-_runtest (AtkObject *obj)
-{
- AtkObject *child_obj;
- AtkTable *table;
- AtkObject *caption;
- gint i;
- gint n_cols, n_rows, n_children;
-
- table = ATK_TABLE (obj);
- n_children = atk_object_get_n_accessible_children (ATK_OBJECT (obj));
- n_cols = atk_table_get_n_columns (table);
- n_rows = atk_table_get_n_rows (table);
- g_print ("n_children: %d n_rows: %d n_cols: %d\n",
- n_children, n_rows, n_cols);
-
- for (i = 0; i < n_rows; i++)
- {
- gint index = atk_table_get_index_at (table, i, expander_column);
- gint index_in_parent;
-
- child_obj = atk_table_ref_at (table, i, expander_column);
- index_in_parent = atk_object_get_index_in_parent (child_obj);
- g_print ("index: %d %d row %d column %d\n", index, index_in_parent, i, expander_column);
-
- g_object_unref (child_obj);
- }
- caption = atk_table_get_caption (table);
- if (caption)
- {
- const gchar *caption_name = atk_object_get_name (caption);
-
- g_print ("Caption: %s\n", caption_name ? caption_name : "<null>");
- }
- for (i = 0; i < n_cols; i++)
- {
- AtkObject *header;
-
- header = atk_table_get_column_header (table, i);
- g_print ("Header for column %d is %p\n", i, header);
- if (header)
- {
- const gchar *name;
- AtkRole role;
- AtkObject *parent;
- AtkObject *child;
- gint index;
-
- name = atk_object_get_name (header);
- role = atk_object_get_role (header);
- parent = atk_object_get_parent (header);
-
- if (parent)
- {
- index = atk_object_get_index_in_parent (header);
- g_print ("Parent: %s index: %d\n", G_OBJECT_TYPE_NAME (parent), index);
- child = atk_object_ref_accessible_child (parent, 0);
- g_print ("Child: %s %p\n", G_OBJECT_TYPE_NAME (child), child);
- if (index >= 0)
- {
- child = atk_object_ref_accessible_child (parent, index);
- g_print ("Index: %d child: %s\n", index, G_OBJECT_TYPE_NAME (child));
- g_object_unref (child);
- }
- }
- else
- g_print ("Parent of header is NULL\n");
- g_print ("%s %s %s\n", G_OBJECT_TYPE_NAME (header), name ? name: "<null>", atk_role_get_name (role));
- }
- }
-}
-
-static void
-row_inserted (AtkObject *obj,
- gint row,
- gint count)
-{
-#if 0
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
-#endif
- gint index;
-
- g_print ("row_inserted: row: %d count: %d\n", row, count);
- index = atk_table_get_index_at (ATK_TABLE (obj), row+1, 0);
- g_print ("index for first column of next row is %d\n", index);
-
-#if 0
- widget = GTK_ACCESSIBLE (obj)->widget;
- tree_view = GTK_TREE_VIEW (widget);
- tree_model = gtk_tree_view_get_model (tree_view);
- if (GTK_IS_TREE_STORE (tree_model))
- {
- GtkTreeStore *tree_store;
- GtkTreePath *tree_path;
- GtkTreeIter tree_iter;
-
- tree_store = GTK_TREE_STORE (tree_model);
- tree_path = gtk_tree_path_new_from_string ("3:0");
- gtk_tree_model_get_iter (tree_model, &tree_iter, tree_path);
- gtk_tree_path_free (tree_path);
- gtk_tree_store_remove (tree_store, &tree_iter);
- }
-#endif
-}
-
-static void
-row_deleted (AtkObject *obj,
- gint row,
- gint count)
-{
-#if 0
- GtkWidget *widget;
- GtkTreeView *tree_view;
- GtkTreeModel *tree_model;
-#endif
- gint index;
-
- g_print ("row_deleted: row: %d count: %d\n", row, count);
- index = atk_table_get_index_at (ATK_TABLE (obj), row+1, 0);
- g_print ("index for first column of next row is %d\n", index);
-
-#if 0
- widget = GTK_ACCESSIBLE (obj)->widget;
- tree_view = GTK_TREE_VIEW (widget);
- tree_model = gtk_tree_view_get_model (tree_view);
- if (GTK_IS_TREE_STORE (tree_model))
- {
- GtkTreeStore *tree_store;
- GtkTreePath *tree_path;
- GtkTreeIter tree_iter, new_iter;
-
- tree_store = GTK_TREE_STORE (tree_model);
- tree_path = gtk_tree_path_new_from_string ("2");
- gtk_tree_model_get_iter (tree_model, &tree_iter, tree_path);
- gtk_tree_path_free (tree_path);
- gtk_tree_store_insert_before (tree_store, &new_iter, NULL, &tree_iter);
- }
-#endif
-}
+++ /dev/null
-#include <string.h>
-#include <atk/atk.h>
-#include <gtk/gtk.h>
-
-static void _traverse_children (AtkObject *obj);
-static void _add_handler (AtkObject *obj);
-static void _check_values (AtkObject *obj);
-static void _value_change_handler (AtkObject *obj,
- AtkPropertyValues *values);
-
-static guint id;
-
-static void _value_change_handler (AtkObject *obj,
- AtkPropertyValues *values)
-{
- const gchar *type_name = g_type_name (G_TYPE_FROM_INSTANCE (obj));
- GValue *value_back, val;
-
- value_back = &val;
-
- if (!ATK_IS_VALUE (obj)) {
- return;
- }
-
- if (strcmp (values->property_name, "accessible-value") == 0) {
- g_print ("_value_change_handler: Accessible Type: %s\n",
- type_name ? type_name : "NULL");
- if(G_VALUE_HOLDS_DOUBLE (&values->new_value))
- {
- g_print( "adjustment value changed : new value: %f\n",
- g_value_get_double (&values->new_value));
- }
-
- g_print("Now calling the AtkValue interface functions\n");
-
- atk_value_get_current_value (ATK_VALUE(obj), value_back);
- g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
- g_print ("atk_value_get_current_value returns %f\n",
- g_value_get_double (value_back) );
-
- atk_value_get_maximum_value (ATK_VALUE (obj), value_back);
- g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
- g_print ("atk_value_get_maximum returns %f\n",
- g_value_get_double (value_back));
-
- atk_value_get_minimum_value (ATK_VALUE (obj), value_back);
- g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
- g_print ("atk_value_get_minimum returns %f\n",
- g_value_get_double (value_back));
-
-
- }
-
-}
-
-static void _traverse_children (AtkObject *obj)
-{
- gint n_children, i;
-
- n_children = atk_object_get_n_accessible_children (obj);
- for (i = 0; i < n_children; i++)
- {
- AtkObject *child;
-
- child = atk_object_ref_accessible_child (obj, i);
- _add_handler (child);
- _traverse_children (child);
- g_object_unref (G_OBJECT (child));
- }
-}
-
-static void _add_handler (AtkObject *obj)
-{
- static GPtrArray *obj_array = NULL;
- gboolean found = FALSE;
- gint i;
-
- /*
- * We create a property handler for each object if one was not associated
- * with it already.
- *
- * We add it to our array of objects which have property handlers; if an
- * object is destroyed it remains in the array.
- */
- if (obj_array == NULL)
- obj_array = g_ptr_array_new ();
-
- for (i = 0; i < obj_array->len; i++)
- {
- if (obj == g_ptr_array_index (obj_array, i))
- {
- found = TRUE;
- break;
- }
- }
- if (!found)
- {
- atk_object_connect_property_change_handler (obj,
- (AtkPropertyChangeHandler*) _value_change_handler);
- g_ptr_array_add (obj_array, obj);
- }
-}
-
-static void _set_values (AtkObject *obj) {
-
- GValue *value_back, val;
- static gint count = 0;
- gdouble double_value;
-
- value_back = &val;
-
- if(ATK_IS_VALUE(obj)) {
- /* Spin button also inherits the text interfaces from GailEntry.
- * Check when spin button recieves focus.
- */
-
- if(ATK_IS_TEXT(obj) && ATK_IS_EDITABLE_TEXT(obj)) {
- if(count == 0) {
- gint x;
- gchar* text;
- count++;
- x = atk_text_get_character_count (ATK_TEXT (obj));
- text = atk_text_get_text (ATK_TEXT (obj), 0, x);
- g_print("Text : %s\n", text);
- text = "5.7";
- atk_editable_text_set_text_contents(ATK_EDITABLE_TEXT(obj),text);
- g_print("Set text to %s\n",text);
- atk_value_get_current_value(ATK_VALUE(obj), value_back);
- g_return_if_fail (G_VALUE_HOLDS_DOUBLE (value_back));
- g_print("atk_value_get_current_value returns %f\n",
- g_value_get_double( value_back));
- }
- } else {
- memset (value_back, 0, sizeof (GValue));
- g_value_init (value_back, G_TYPE_DOUBLE);
- g_value_set_double (value_back, 10.0);
- if (atk_value_set_current_value (ATK_VALUE (obj), value_back))
- {
- double_value = g_value_get_double (value_back);
- g_print("atk_value_set_current_value returns %f\n",
- double_value);
- }
- }
- }
-}
-
-static void _check_values (AtkObject *obj)
-{
- static gint calls = 0;
- AtkRole role;
-
- g_print ("Start of _check_values\n");
-
- _set_values(obj);
-
- _add_handler (obj);
-
- if (++calls < 2)
- {
- /*
- * Just do this on this on the first 2 objects visited
- */
- atk_object_set_name (obj, "test123");
- atk_object_set_description (obj, "test123");
- }
-
- role = atk_object_get_role (obj);
-
- if (role == ATK_ROLE_FRAME || role == ATK_ROLE_DIALOG)
- {
- /*
- * Add handlers to all children.
- */
- _traverse_children (obj);
- }
- g_print ("End of _check_values\n");
-}
-
-static void
-_create_event_watcher (void)
-{
- id = atk_add_focus_tracker (_check_values);
-}
-
-int
-gtk_module_init(gint argc, char* argv[])
-{
- g_print("testvalues Module loaded\n");
-
- _create_event_watcher();
-
- return 0;
-}